简体   繁体   English

如果包含列表,如何从 Firebase 实时数据库中检索对象?

[英]How can I retrieve an object from the Firebase RealTime Database if it contains a List?

I'm trying to learn how to use Firebase, and decided to make a simple android application that uses the Firebase RealTime Database.我正在尝试学习如何使用 Firebase,并决定制作一个使用 Firebase 实时数据库的简单 android 应用程序。 The game requires a host who hosts a lobby, and players who can join that lobby.游戏需要一个主持大厅的主持人,以及可以加入该大厅的玩家。 I made a host class that has a bunch of data types, among which is a list (the game involves using hints given to players by the host).我做了一个主机类,它有一堆数据类型,其中有一个列表(游戏涉及使用主机给玩家的提示)。 I'm running into problems when I try to read from the database.当我尝试从数据库中读取时遇到了问题。

My lobby is a listview that I want to populate with a list of hosts in the database, but when I try to read from it I get this nasty error:我的大厅是一个列表视图,我想用数据库中的主机列表填充它,但是当我尝试从中读取时,我收到了这个令人讨厌的错误:

com.google.firebase.database.DatabaseException: Class java.util.List has generic type parameters, please use GenericTypeIndicator instead com.google.firebase.database.DatabaseException:类 java.util.List 具有通用类型参数,请改用 GenericTypeIndicator

I know that there are other questions about the same error, but I couldn't apply those answers with much success.我知道关于同一错误还有其他问题,但我无法成功应用这些答案。 I'm quite new to android development and would greatly appreciate any help.我对 android 开发很陌生,非常感谢任何帮助。

Here is my user-defined class:这是我的用户定义类:

public class HostPlayer {

    private String hostName;
    private String photoUrl;
    private String primaryHint;
    List<String> hints = new ArrayList<String>();
    private int numHints;
    private int numTime;
    private boolean inProgress = false;

    public HostPlayer() {

    }

    public HostPlayer(String hostName, int numHints, int numTime, List<String> hints, String primaryHint, String photoUrl) {
        this.hostName = hostName;
        this.numHints = numHints;
        this.numTime = numTime;
        this.hints = hints;
        this.primaryHint = primaryHint;
        this.photoUrl = photoUrl;
        this.inProgress = false;
    }

    public void setPhotoUrl(String photoUrl) {this.photoUrl = photoUrl;}

    public void setPrimaryHint(String primaryHint) {this.primaryHint = primaryHint;}

    public void setHints(List hints) {this.hints = hints;}

    public String getHostName() {return this.hostName;}

    public int getNumHints() {return this.numHints;}

    public  int getNumTime() {return this.numTime;}

    public String getPrimaryHint() {return this.primaryHint;}

    public List getHints() {return this.hints;}

    public void setInProgress() {this.inProgress = true;}

    public boolean getInProgress() {return this.inProgress;}
}

Here is my code where I read from the database:这是我从数据库中读取的代码:

public class JoinGame extends AppCompatActivity {

    ListView lv;

    private FirebaseDatabase pFireBaseDatabase;
    private DatabaseReference pDatabaseReference;
    private ChildEventListener pChildEventListener;

    List<HostPlayer> hostPlayerList = new ArrayList<>();

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

        pFireBaseDatabase = FirebaseDatabase.getInstance();
        pDatabaseReference = pFireBaseDatabase.getReference().child("hosts");

        pChildEventListener = new ChildEventListener() {
            @Override
            public void onChildAdded(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) {
                HostPlayer hostPlayer = snapshot.getValue(HostPlayer.class); //this is where the error happens
                hostPlayerList.add(hostPlayer);
            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {

            }
        };
        pDatabaseReference.addChildEventListener(pChildEventListener);

        lv = findViewById(R.id.listView_hosts);

        ArrayAdapter<HostPlayer> hostPlayerArrayAdapter = new ArrayAdapter<HostPlayer>(
                this, android.R.layout.simple_list_item_1, hostPlayerList
        );//making an arrayAdapter out of the list of HostPlayer objects

        lv.setAdapter(hostPlayerArrayAdapter);
    }
}

This is what the database JSON is structured like:数据库 JSON 的结构如下:

{
  "hosts" : {
    "some-data-key" : {
      "hints" : [ "first hint", "second hint" ],
      "hostName" : "mom",
      "inProgress" : false,
      "numHints" : 3,
      "numTime" : 30,
      "primaryHint" : "Living Room"
    }
  },
  "players" : {
    "another-data-key" : {
      "hostName" : "firstName",
      "inProgress" : false,
      "numHints" : 0,
      "numTime" : 0
    }
  }
}

I understand that the list "hints" is causing this error, but still don't understand why and how I can fix it.我知道列表“提示”导致了这个错误,但仍然不明白为什么以及如何修复它。 I would greatly appreciate any explanations and/or solutions.我将不胜感激任何解释和/或解决方案。 Thanks for your time and help.感谢您的时间和帮助。

Edit: I forgot to paste the logcat, here it is:编辑:我忘了粘贴 logcat,这里是:

2021-10-23 16:11:20.732 21137-21137/com.example.treasurehunt E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.treasurehunt, PID: 21137
    com.google.firebase.database.DatabaseException: Class java.util.List has generic type parameters, please use GenericTypeIndicator instead
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToClass(CustomClassMapper.java:224)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToType(CustomClassMapper.java:179)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.access$100(CustomClassMapper.java:48)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper$BeanMapper.deserialize(CustomClassMapper.java:593)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper$BeanMapper.deserialize(CustomClassMapper.java:563)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertBean(CustomClassMapper.java:433)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToClass(CustomClassMapper.java:232)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertToCustomClass(CustomClassMapper.java:80)
        at com.google.firebase.database.DataSnapshot.getValue(DataSnapshot.java:203)
        at com.example.treasurehunt.JoinGame$1.onChildAdded(JoinGame.java:41)
        at com.google.firebase.database.core.ChildEventRegistration.fireEvent(ChildEventRegistration.java:79)
        at com.google.firebase.database.core.view.DataEvent.fire(DataEvent.java:63)
        at com.google.firebase.database.core.view.EventRaiser$1.run(EventRaiser.java:55)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

One way of doing it might look like this;一种方法可能看起来像这样;

public class HostPlayer {

    ...
    List<String> hints = new ArrayList<String>();

    ...

    @Exclude //We are hiding this method from Firebase because we are gonna handle it manually.
    public void setHints(List<String> hints) {this.hints = hints;}
}

and

    pChildEventListener = new ChildEventListener() {
        @Override
        public void onChildAdded(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) {
            // This must be error-free now but the hints list will be missing. We are gonna add them manually.
            // (All fields except "hintsList" will be set automatically.)
            HostPlayer hostPlayer = snapshot.getValue(HostPlayer.class);

            // We have the HostPlayer's snapshot. And we need the "hints" list which is one of its children.
            DataSnapshot hintsSnapshot = dataSnapshot.child("hints");
            
            
            // Iterate through the snapshot and add the hints to the list.
            List<String> hintsList = new ArrayList<>();
            for (DataSnapshot currentHint : hintsSnapshot.getChildren()) {
                String hint = currentHint.getValue();
                hintsList.add(hint);
            }

            hostPlayer.setHints(hintsList);//We have the host player with the hintsList!
            ...
        }
        ...
    };

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何从Firebase实时数据库中检索列表? - How to retrieve list from firebase realtime database? 如何从 Firebase 实时数据库中检索值? - How can I retrieve the value from Firebase Realtime database? 如何从 Firebase 实时数据库中检索用户用户名以获取欢迎回复消息? - How can I retrieve a users username from Firebase Realtime database for a welcome back message? 如何在两个不同的活动中从Firebase实时数据库检索数据 - How can I retrieve data from Firebase Realtime Database in two different activity 如何从 firebase 实时数据库中检索两个不同的值并在 onDataChange 方法之外使用? - How can I retrieve two different values from firebase realtime database and use outside onDataChange method? 如何从 Firebase 实时数据库中检索用户名 - How to retrieve a username from firebase realtime database 如何从 Firebase 的实时数据库中检索数据? - How to retrieve data from realtime database in Firebase? 如何在 firebase 中实时检索此元素? - How can I retrieve this element in firebase realtime? 如何从Firebase实时数据库获取下一个孩子的数据并将其显示在列表视图中 - How I can get data of next child and show it in list view from firebase realtime database 如何使用 Firebase 实时数据库中的关联节点名称列表填充“微调器”? - How can I populate the 'Spinner' with a list of associated node names from the Firebase Realtime Database?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM