Firestore: Found conflicting getters for name isTe

2020-05-03 11:14发布

问题:

I tried to look at similar questions but they are of no use for me.

I have a class:

data class TextMessage(val text: String,
                   override val time: Date,
                   override val senderId: String,
                   override val isText: Boolean = true)
: Message{
constructor() : this("", Date(0), "") }

Then I try to store an instance of it in Firestore:

fun sendTextMessage(message: TextMessage, channelId: String) {
    chatChannelsCollectionRef.document(channelId)
            .collection("messages")
            .add(message)
}

For some reason whenever I call sendTextMessage I get this exception:

java.lang.RuntimeException: Found conflicting getters for name isText on class com.resocoder.firemessageprep.model.TextMessage
at com.google.android.gms.internal.zzevb$zza.<init>(Unknown Source:191)
at com.google.android.gms.internal.zzevb.zzg(Unknown Source:12)
at com.google.android.gms.internal.zzevb.zza(Unknown Source:285)
at com.google.android.gms.internal.zzevb.zzbw(Unknown Source:2)
at com.google.firebase.firestore.zzk.zzcd(Unknown Source:36)
at com.google.firebase.firestore.CollectionReference.add(Unknown Source:5)
at com.resocoder.firemessageprep.util.FirestoreUtil.sendTextMessage(FirestoreUtil.kt:138)
at com.resocoder.firemessageprep.ChatActivity$onCreate$1$2.onClick(ChatActivity.kt:52)
at android.view.View.performClick(View.java:6256)
at android.view.View$PerformClick.run(View.java:24701)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)

                                                                               at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

It doesn't make sense. I know that TextMessage implements an interface which has a property isText but that shouldn't be the cause... right?

Thanks for reading this far!

回答1:

The problem in your code is that you are using a field named isText. In Cloud Firestore the coresponding getter is getText() and NOT getIsText() as expected.

If you try to change the name of the field in, let's say, izText instead of isText and to have the corresponding getter like getIzText(), your code will work perfectly fine. Firestore removes the is prefix from the getter, that's why you have that conflict. For more informations, you can also take a look at this video.

If you decide to change that field name, don't forget to remove the old data and add fresh one.



回答2:

The generated class file for TextMessage has the following methods defined. This was obtained by running javap against it:

public final java.lang.String getText();
public java.util.Date getTime();
public java.lang.String getSenderId();
public boolean isText();

The Firestore SDK is confused because it derives the names of document properties from the names of the getters in the class. So, by JavaBean convention, getText() becomes "text". And isText() also becomes "text". Firestore doesn't know which one you wanted to use for the document property called "text", hence the message.

You will have to change the name of one or the other to avoid this conflict. Alternately, you can try to use the PropertyName annotation to alter Firestore's naming of the field for either one.