Java 访问Firebase中的项目数组

Java 访问Firebase中的项目数组,java,android,firebase,firebase-realtime-database,Java,Android,Firebase,Firebase Realtime Database,事实上我有两个问题都很相似。我的问题概述如下: 我正在开发的图书馆应用程序与书籍和作者有一对多的关系,这意味着一本书可以有许多作者。一个样本作者和一本书作为图片附上 问题1。如何搜索特定作者?对于一本只有一位作者的书,它总是有第零个索引。一本有多个作者的书怎么样?如果是这样,同一作者也可以存在于其他索引中。我想从一个特定的作者那里得到所有的书,我想知道最好的方法是什么 问题2。如何查明作者是否有以其名义出版的书籍。事实上,我可以得到所有的书并反复阅读。然而,仅仅做一个“存在”操作就需要大量的

事实上我有两个问题都很相似。我的问题概述如下:

我正在开发的图书馆应用程序与书籍和作者有一对多的关系,这意味着一本书可以有许多作者。一个样本作者和一本书作为图片附上

问题1。如何搜索特定作者?对于一本只有一位作者的书,它总是有第零个索引。一本有多个作者的书怎么样?如果是这样,同一作者也可以存在于其他索引中。我想从一个特定的作者那里得到所有的书,我想知道最好的方法是什么

问题2。如何查明作者是否有以其名义出版的书籍。事实上,我可以得到所有的书并反复阅读。然而,仅仅做一个“存在”操作就需要大量的带宽。有没有简单的方法


提前谢谢

您可以迁移到Cloud Firestore,但如果您已经在使用Firebase实时数据库,您可以实现这一点,但是不需要对数据库进行一些更改

我想从一个特定的作者那里得到所有的书,我想知道最好的方法是什么

不幸的是,使用实际的数据库结构无法实现所需的功能。为了从一个特定的作者获得所有的书,你应该考虑扩充你的数据结构以允许反向查找。这意味着您需要创建一个名为
books
的新顶级集合,您应该将特定作者的所有书籍存储为
book
对象。您的数据库架构应该如下所示:

Firebase-root
  |
  --- books
        |
        --- authorIdOne
              |
              --- bookIdOne
              |     |
              |     --- id: "bookIdOne"
              |     |
              |     --- nameInEnglish: "nameInEnglish"
              |     |
              |     --- nameInSinhalese: "nameInSinhalese"
              |
              --- bookIdTwo
                    |
                    --- id: "bookIdTwo"
                    |
                    --- nameInEnglish: "nameInEnglish"
                    |
                    --- nameInSinhalese: "nameInSinhalese"
要从特定作者处获取所有书籍,您需要在其id(
authorIdOne
)上附加一个侦听器,并遍历其子项

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference yourRef = authorIdOneRef.child("books").child(authorIdOne);
authorIdOneRef.addListenerForSingleValueEvent(/* ... */);
如何查明作者是否有其名下的书籍

要解决此问题,需要对
DataSnapshot
对象使用
exists()
方法。假设您使用的是名为
Book
的模型类,请参见以下代码行:

ValueEventListener valueEventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        if(dataSnapshot.exists()) {
            for(DataSnapshot ds : dataSnapshot.getChildren()) {
                Book book = ds.getValue(Book.class);
                Log.d("TAG", book.getNameInEnglish());
            }
        }
    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {}
};
authorIdOneRef.addListenerForSingleValueEvent(valueEventListener);
但是同样的事情也可以通过使用String类来实现

ValueEventListener valueEventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        if(dataSnapshot.exists()) {
            for(DataSnapshot ds : dataSnapshot.getChildren()) {
                String nameInEnglish = ds.child("nameInEnglish").getValue(String.class);
                Log.d("TAG", nameInEnglish);
            }
        }           
    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {}
};
authorIdOneRef.addListenerForSingleValueEvent(valueEventListener);

请注意,Firebase实时数据库不存储阵列。你实际上拥有的是一个物体。查看更多详细信息。

我建议使用Firestore,因为它有更好的查询功能。参考:有没有一种简单的方法可以将我所有的现有数据迁移到CloudFireStore?这些帖子可能会有所帮助。(奖金)是我在网上找到的信息丰富的帖子。非常感谢链接和提示。我已经学习了很多关于如何移动我的数据的知识,我想我可以用一个脚本来完成。很好,你发现它很有用,请放弃投票,这样其他人就可以找到它。干杯!非常感谢你的详细回答。正如你提到的,我担心我的数据库结构似乎是这里的问题。因此,考虑到这样一个事实,我认为现在转移到云Firestore可能是最好的选择,它将确保在我实现未来的功能时减少麻烦。在这种情况下,祝你好运。这是一个很好的产品,很容易学。如果你认为我的答案对你有帮助,请考虑接受并投票。我会很感激的。谢谢就这么做了!因为我没有足够的代表,所以我不能投票。