【问题标题】:Firebase unable to retrieve data using class [duplicate]Firebase 无法使用类检索数据 [重复]
【发布时间】:2018-09-10 15:59:49
【问题描述】:

我有一些功能齐全的代码行检索每个数据,但未能使用类检索它们。例如:这些行运行良好。

double value = (double) ds.child("player1score").getValue();
long value = (long) ds.child("point").getValue();

然而,当使用类检索时,会发生错误。 这是我的代码的全貌,不确定是否足以解决问题,请随时让我知道还需要什么,非常感谢任何建议,谢谢!

Round().class

public class Round {
public double player1score;
public double player2score;
public double player3score;
public double player4score;
public long point;

//Constructor
public Round(double player1score, double player2score, double player3score, double player4score, long point) {
    this.player1score = player1score;
    this.player2score = player2score;
    this.player3score = player3score;
    this.player4score = player4score;
    this.point = point;

//Below are All the getter and setter etc
}

我的 MainActivity.class.onCreate()

//Declare Variables
UserId = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference gameInfoRef = rootRef.child("user").child(UserId).child("gameInfo");
DatabaseReference gameRecordRef = rootRef.child("user").child(UserId).child("gameRecord");

String gameKey = "-LLyXhetqj9mj5fgh9bn";

在 onCreate() 下:

gameRecordRef.child(gameKey).addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for (DataSnapshot ds : dataSnapshot.getChildren()) {
                ListView lv_history = (ListView) findViewById(R.id.lv_history);

                ArrayList<Round> ResultList = new ArrayList<>();

                //This line is where the error pointed to
                Round round = (Round) ds.getValue(Round.class);

                ResultList.add(round);

                ivd_HistoryAdapter adapter = new ivd_HistoryAdapter(id_History.this, ResultList);
                lv_history.setAdapter(adapter);
            }
        }

文本中的 Firebase 结构:

  "user": 
       "5xGKRXeHgThQy70lduPEp3mosTj1": 
             "gameRecord": 
                   "-LLyXhetqj9mj5fgh9bn": 
                        "player1score": 0.5,
                        "player2score": 0.5,
                        "player3score": 0.5,
                        "player4score": 0.5,
                        "point": 5

Logcat 错误:

com.google.firebase.database.DatabaseException:类 viwil.mahjongcal.Round 未定义无参数构造函数。如果您使用 ProGuard,请确保未剥离这些构造函数。 在 com.google.android.gms.internal.zzelx.zze(未知来源) 在 com.google.android.gms.internal.zzelw.zzb(未知来源) 在 com.google.android.gms.internal.zzelw.zza(未知来源) 在 com.google.firebase.database.DataSnapshot.getValue(未知来源) 在 viwil.mahjongcal.id_History$1.onDataChange(id_History.java:51) 在 com.google.android.gms.internal.zzegf.zza(未知来源) 在 com.google.android.gms.internal.zzeia.zzbyc(未知来源) 在 com.google.android.gms.internal.zzeig.run(未知来源) 在 android.os.Handler.handleCallback(Handler.java:761) 在 android.os.Handler.dispatchMessage(Handler.java:98) 在 android.os.Looper.loop(Looper.java:156) 在 android.app.ActivityThread.main(ActivityThread.java:6523) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:942) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:832)

错误指向这一行:(id_History.java:51)

    Round round = ds.getValue(Round.class);

Firebase 截图:

【问题讨论】:

    标签: java android firebase firebase-realtime-database


    【解决方案1】:

    您收到以下错误:

    FATAL EXCEPTION: ... does not define a no-argument constructor
    

    因为您的Round 类没有定义no-argument constructor

    JavaBeans require a no-argument constructor 出现在模型类中。

    在Java 中,当一个类根本没有构造函数时,Java 编译器会自动添加一个默认的no-argument constructor。在类中定义 any 构造函数的那一刻,默认的无参数构造函数就会消失。

    在您的代码中,您的 Round 类定义了这样一个包含五个参数的构造函数:

    public Round(double player1score, double player2score, double player3score, double player4score, long point) {}
    

    只要这个构造函数存在并且你没有定义no-argument constructor,那个类就不会有一个。

    要解决这个问题,您可以从类中删除该构造函数,或者手动添加no-argument constructor,如下所示:

    public Round() {}
    

    当 Firebase 实时数据库 SDK 反序列化来自数据库的对象时,它要求所有正在使用的对象都必须具有此构造函数,以便可以使用它来实例化对象。对象中的字段通过使用公共 setter 方法或直接访问公共成员来设置。

    您的Round 类没有公共no-arg constructor,SDK 并不真正知道如何创建它的实例。所以必须要有。

    另外请注意,setter 和 getter 不是必需的。 Setter 始终是可选的,因为如果 JSON 属性没有 setter,Firebase 客户端会将值直接设置到字段中。也不需要带参数的构造函数。两者都是惯用的,并且有很好的情况下没有它们的类。如果您将字段设为公开,则 getter 也是可选的。

    【讨论】:

    • 恕我直言,更像是从 stackoverflow.com/a/47706656/4409113 复制粘贴给我的,但希望这对 OP 有所帮助。
    • @ʍѳђઽ૯ท 我想我已经提供了一些可以帮助 OP 的更多细节。感谢您的评论。
    • 当然!不能否认这一点。希望对您有所帮助。
    • @ʍѳђઽ૯ท 也标记为重复。再次感谢!干杯!
    • @ʍѳђઽ૯ท Alex 的回答确实有帮助并详细解释,我非常感谢他的帮助。现在问题完美解决了!
    猜你喜欢
    • 2020-07-07
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-27
    • 2015-08-19
    相关资源
    最近更新 更多