0

I have a model data class with a few attributes. I have added some data into the Firestore and read them using this model class. Later, I decided to add a few more attributes in the model class but I have not added new fields in the Firestore database. When I read the data like before, my app crashes. This is obvious that as we go further we would add more details but we may or may not add these new details to old items that are already added to the database. How can I handle this situation?

This is how I am reading from the `Firestore'

mFireStore.collection("product_details")
                .get()
                .addOnCompleteListener {
                    if (it.isSuccessful) {
                        for (document in it.result) {
                            val product = document.toObject(ProductDetails::class.java)
                            product.product_id = document.id
                            productsList.add(product)

                        }
                    } else {
                    }
                    tempProductsList.addAll(productsList)
                    listProducts()
                }
                .addOnFailureListener {
                }

and this is where I am getting the error.

val product = document.toObject(ProductDetails::class.java)

Edit: A sample of my model class is provided below. It has a lot of fields but I copied only a few here. 'min_order_quantity' and 'max_order_quantity' are the two that I newly added in this model class and the items already in the Firestore doesn't have these fields.

@Parcelize
data class ProductDetails(
    var product_id: String? = "",
    val title: String = "",
    val mrp: String= "0.00",
    val price: String = "0.00",
    val description: String = "",
    var min_order_quantity: String="",
    var max_order_quantity: String="",
) : Parcelable

Logcat:

Process: com.abc.xyz, PID: 19223
java.lang.VerifyError: Verifier rejected class com.abc.xyz.models.ProductDetails: void com.abc.xyz.models.ProductDetails.<init>() failed to verify: void com.abc.xyz.models.ProductDetails.<init>(): [0x1FB] Rejecting invocation, expected 1 argument registers, method signature has 2 or more (declaration of 'com.abc.xyz.models.ProductDetails' appears in /data/data/com.abc.xyz/code_cache/.overlay/base.apk/classes5.dex)
    at java.lang.reflect.Constructor.newInstance0(Native Method)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
    at com.google.firebase.firestore.util.ApiUtil.newInstance(ApiUtil.java:43)
    at com.google.firebase.firestore.util.CustomClassMapper$BeanMapper.deserialize(CustomClassMapper.java:757)
    at com.google.firebase.firestore.util.CustomClassMapper$BeanMapper.deserialize(CustomClassMapper.java:741)
    at com.google.firebase.firestore.util.CustomClassMapper.convertBean(CustomClassMapper.java:542)
    at com.google.firebase.firestore.util.CustomClassMapper.deserializeToClass(CustomClassMapper.java:253)
    at com.google.firebase.firestore.util.CustomClassMapper.convertToCustomClass(CustomClassMapper.java:100)
    at com.google.firebase.firestore.DocumentSnapshot.toObject(DocumentSnapshot.java:183)
    at com.google.firebase.firestore.QueryDocumentSnapshot.toObject(QueryDocumentSnapshot.java:116)
    at com.google.firebase.firestore.DocumentSnapshot.toObject(DocumentSnapshot.java:161)
    at com.google.firebase.firestore.QueryDocumentSnapshot.toObject(QueryDocumentSnapshot.java:97)
    at com.abc.xyz.ui.fragments.HomeFragment.getProductList$lambda-7(HomeFragment.kt:431)
    at com.abc.xyz.ui.fragments.HomeFragment.lambda$QeVGu-lWsXTqkddk(Unknown Source:0)
    at com.abc.xyz.ui.fragments.-$$Lambda$HomeFragment$QeVGu-lWsXTqkddk.onComplete(Unknown Source:2)
    at com.google.android.gms.tasks.zzj.run(com.google.android.gms:play-services-tasks@@17.2.0:4)
    at android.os.Handler.handleCallback(Handler.java:938)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:246)
    at android.app.ActivityThread.main(ActivityThread.java:8633)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
Codist
  • 737
  • 8
  • 23
  • IIRC in case of missing fields, the model fields are initialized with default values. Can you add you `ProductDetails` model in the question? – Arpit Shukla Nov 12 '21 at 18:22
  • @ArpitShukla Question is updated, please check. – Codist Nov 12 '21 at 18:32
  • Also add the stacktrace of the crash that you are getting. – Arpit Shukla Nov 12 '21 at 18:34
  • @ArpitShukla Question is updated. – Codist Nov 12 '21 at 18:49
  • This error is not related to firebase fields. Try doing `Invalidate Caches and Restart`. Refer [this](https://stackoverflow.com/questions/28031905/java-lang-verifyerror-verifier-rejected-class-on-lollipop-when-using-release-ap) related question. – Arpit Shukla Nov 12 '21 at 18:51
  • 1
    This isn't your current problem, but it's likely going to be your next one if you don't fix it. `productsList.addAll(productsList)` This doubles everything in your list, and I'm guessing that's not what you intend to do. – Tenfour04 Nov 12 '21 at 18:52
  • @Tenfour04 Can you elaborate a bit on what you meant by "doubles everything in your list"? – Codist Nov 12 '21 at 19:00
  • 1
    If you add everything in a list back into the same list, everything will now be in the list twice. Probably you intended to do something different than that... – Tenfour04 Nov 12 '21 at 19:01
  • @ArpitShukla Still same error. Did you mean that if a field is not found in the `Firestore` which a models data class has won't cause an error? – Codist Nov 12 '21 at 19:02
  • @Tenfour04 Keen observation and thanks for that. Since I made some changes while asking the question, I made a mistake but that's not what I actually have. I have corrected it in the question to `tempProductsList.addAll(productsList)` – Codist Nov 12 '21 at 19:10
  • 1
    @Codist Yes, if you have a field in your model that isn't present in firestore, it will be initialized to its default value (in your case `min_order_quantity` will be initialized to `""`). Also if you have a field in firestore that isn't there in your model, it will be skipped while deserializing. – Arpit Shukla Nov 13 '21 at 04:06
  • As I understand, there is a limit to the number of parameters a data class can have and I think it's 245. I already had 245 and when I add another two the issue started. When I removed any two parameters, it works. Thanks for your insights. – Codist Nov 13 '21 at 09:06

2 Answers2

1

This isn't a problem with firebase fields. Try clearing your caches and restarting your computer. Please see this related question for more information:

java.lang.VerifyError: Verifier rejected class on Lollipop when using release APK

If you have a field in your model that isn't in the Firestore, it will be initialized to its default value. (in your case, "").

Additionally, if a field in the firestore does not exist in your model, it will be skipped during deserialization. A data class can only have a certain number of parameters, which probably is 245.

0

As I understand, there is a limit to the number of parameters a data class can have and I think it's 245. I already had 245 and when I add another two the issue started. When I removed any two parameters, it works. Thanks for your insights

Codist
  • 737
  • 8
  • 23