在Firestore中使用collection.add()使应用程序崩溃

时间:2018-11-14 04:00:11

标签: android firebase google-cloud-firestore

我是Android开发的新手,所以如果听起来很琐碎或时间太长,请原谅我,但是我在尝试将项目添加到Firestore中的集合时遇到了麻烦。

我在教程的注释部分中的某个地方读到了这种情况,该情况发生在API 25(我使用的是24)以下,但是我不确定为什么。

这是我的代码的一部分:

FirebaseFirestore db;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_registro);

    FirebaseFirestore firestore = FirebaseFirestore.getInstance();
    FirebaseFirestoreSettings settings = new FirebaseFirestoreSettings.Builder()
            .setTimestampsInSnapshotsEnabled(true)
            .build();
    firestore.setFirestoreSettings(settings);

    db = FirebaseFirestore.getInstance();
}

public void sendInfo(View view){
        CollectionReference dbArtists = db.collection("artistas");
        Artist a = new Artist("0", "A", 10);
        dbArtists.add(a)
    }

sendInfo与正常工作的按钮相关联。使应用程序崩溃的行是

dbArtists.add(a)

因此logcat发出警告,指出:

com.esiete.anapptitle W/Firestore: (0.6.6-dev) [Firestore]: The behavior for java.util.Date objects stored in Firestore is going to change AND YOUR APP MAY BREAK.
To hide this warning and ensure your app does not break, you need to add the following code to your app before calling any other Cloud Firestore methods:

FirebaseFirestore firestore = FirebaseFirestore.getInstance();
FirebaseFirestoreSettings settings = new FirebaseFirestoreSettings.Builder()
    .setTimestampsInSnapshotsEnabled(true)
    .build();
firestore.setFirestoreSettings(settings);

With this change, timestamps stored in Cloud Firestore will be read back as com.google.firebase.Timestamp objects instead of as system java.util.Date objects. So you will also need to update code expecting a java.util.Date to instead expect a Timestamp. For example:

// Old:
java.util.Date date = snapshot.getDate("created_at");
// New:
Timestamp timestamp = snapshot.getTimestamp("created_at");
java.util.Date date = timestamp.toDate();

Please audit all existing usages of java.util.Date when you enable the new behavior. In a future release, the behavior will be changed to the new behavior, so if you do not follow these steps, YOUR APP MAY BREAK.

添加上述代码后,崩溃仍然存在。 Logcat显示:

8-11-13 21:44:09.290 30030-30030/com.esiete.anapptitle D/AndroidRuntime: Shutting down VM
2018-11-13 21:44:09.294 30030-30030/com.esiete.anapptitle E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.esiete.anapptitle, PID: 30030
    java.lang.IllegalStateException: Could not execute method for android:onClick
        at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:390)
        at android.view.View.performClick(View.java:5612)
        at android.view.View$PerformClick.run(View.java:22285)
        at android.os.Handler.handleCallback(Handler.java:751)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6123)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757)
     Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Method.invoke(Native Method)
        at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:385)
        at android.view.View.performClick(View.java:5612) 
        at android.view.View$PerformClick.run(View.java:22285) 
        at android.os.Handler.handleCallback(Handler.java:751) 
        at android.os.Handler.dispatchMessage(Handler.java:95) 
        at android.os.Looper.loop(Looper.java:154) 
        at android.app.ActivityThread.main(ActivityThread.java:6123) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757) 
     Caused by: java.lang.RuntimeException: No properties to serialize found on class com.esiete.anapptitle.Artist
        at com.google.firebase.firestore.g.zzg$zza.<init>(SourceFile:643)
        at com.google.firebase.firestore.g.zzg.zza(SourceFile:331)
        at com.google.firebase.firestore.g.zzg.zzb(SourceFile:152)
        at com.google.firebase.firestore.g.zzg.zza(SourceFile:1085)
        at com.google.firebase.firestore.UserDataConverter.convertPOJO(SourceFile:421)
        at com.google.firebase.firestore.CollectionReference.add(SourceFile:125)
        at com.esiete.anapptitle.RegistroActivity.enviarRegistro(RegistroActivity.java:82)
        at java.lang.reflect.Method.invoke(Native Method) 
        at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:385) 
        at android.view.View.performClick(View.java:5612) 
        at android.view.View$PerformClick.run(View.java:22285) 
        at android.os.Handler.handleCallback(Handler.java:751) 
        at android.os.Handler.dispatchMessage(Handler.java:95) 
        at android.os.Looper.loop(Looper.java:154) 
        at android.app.ActivityThread.main(ActivityThread.java:6123) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757) 
2018-11-13 21:44:09.298 4088-5186/? W/ActivityManager:   Force finishing activity com.esiete.anapptitle/.RegistroActivity
2018-11-13 21:44:09.306 4088-30868/? W/DropBoxManagerService: Dropping: data_app_crash (1752 > 0 bytes)

非常感谢您的帮助或建议。

编辑:添加艺术家类代码。

package com.esiete.anapptitle;

public class Artist {
    private String artistID;
    private String name;
    private int sales;

    public Artist() {
    }

    public Artist(String artistID, String name, int sales) {
        this.artistID = artistID;
        this.name = name;
        this.sales = sales;
    }
}

1 个答案:

答案 0 :(得分:4)

您的Artist类不具有Firebase知道如何与数据库进行序列化的信息。为了了解这一点,该类需要具有公共字段或公共getter和setter方法。

假设数据库中的Artist文档具有以下三个字段:

artistId: "0"
name: "A"
sales: 10

这意味着您需要这个Java类:

public class Artist {
    public String artistId;
    public String name;
    public long sales;
}

此处的每个公共字段都与数据库中文档的确切字段名称匹配,这是Firebase客户端可以读取/写入正确值的方式。

或者,您可以拥有这个Java类:

public class Artist {
    String artistId;
    String name;
    long sales;

    public Artist() {} // Empty constructor is required
    public Artist(String artistId, String name, long sales) {
        this.artistId = artistId;
        this.name = name;
        this.sales = sales;
    }

    public String getArtistId() { return this.artistId; }
    public void setArtistId(String artistId) { this.artistId = artistId; }
    public String getName() { return this.name; }
    public void setName(String name) { this.name = name; }
    public long getRanking() { return this.ranking; }
    public void setRanking(long ranking) { this.ranking = ranking; }
}

第二个类遵循JavaBean命名约定,这意味着getId/setId定义属性id,该属性再次与数据库中的确切字段名称匹配。