【问题标题】:How to listen to changes in Firebase database collection?如何监听 Firebase 数据库集合的变化?
【发布时间】:2020-06-10 12:17:51
【问题描述】:

我有以下代码:

someDocumentRef.collection("data").get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {

    @Override
    public void onComplete(@NonNull Task<QuerySnapshot> task) {
        if (task.isSuccessful()) {
            RelativeLayout emptyLayout = fragmentView.findViewById(R.id.empty_layout);
            if (task.getResult() == null || task.getResult().isEmpty()) {
                emptyLayout.setVisibility(View.VISIBLE);
                rv.setVisibility(View.GONE);
            } else {
                Map<Character,List<QueryDocumentSnapshot>> dataDoc = new HashMap<>();
                for (QueryDocumentSnapshot document : task.getResult()) {
                    char letter = getFirstLetter(document.getString("full_name"));
                    List<QueryDocumentSnapshot> l = dataDoc.get(letter);
                    if (l == null) {
                        l = new ArrayList<>();
                        l.add(document);
                        dataDoc.put(letter, l);
                    } else {
                        l.add(document);
                    }
                }

                // Create recycler view
                emptyLayout.setVisibility(View.GONE);
                rv.setVisibility(View.VISIBLE);
                adapter = new DataAdapter(getActivity(), dataDoc);
                rv.setLayoutManager(new LinearLayoutManager(getActivity()));
                rv.setAdapter(adapter);
            }
        }
    }
});

在我的onCreateView 方法(片段)中。基本上,它从 Firebase 数据库的集合 data 中获取所有文档,并将其传递给适配器以创建回收器视图。效果很好,但我的问题是如何监听数据库中的变化,一旦插入或删除了一些新文档,更新回收器视图?请注意,我不使用FirestoreRecyclerAdapter 适配器,而是我的自定义适配器。另外,我正在使用 Firebase Cloud 数据库。

【问题讨论】:

  • 使用 addOnValueChangeListener ,它的 onDataChange 方法返回一个数据快照。因此,当您的数据库更新时,总会有那个监听器在监听。然后在适配器中添加一个方法来接收新数据
  • 所以不可能在集合上设置监听器?如果我为每个文档设置了一个监听器,我该如何更新 RV?
  • 对不起,我说的是实时数据库而不是火存储。但是我不确定firestore是实时的,我没用过,我建议你切换到实时数据库
  • @Jason 不幸的是我不能。如果其他人有想法,我会等待。谢谢。

标签: java android firebase android-recyclerview google-cloud-firestore


【解决方案1】:

您实际上可以收听 firebase 的变化,抱歉之前的评论。我检查了消防店的文件,我看到了这个

final DocumentReference docRef = 
db.collection("cities").document("SF");
docRef.addSnapshotListener(new 
 EventListener<DocumentSnapshot>() {
  @Override
  public void onEvent(@Nullable DocumentSnapshot 
 snapshot,
                    @Nullable FirebaseFirestoreException e) {
    if (e != null) {
        Log.w(TAG, "Listen failed.", e);
        return;
    }

    if (snapshot != null && snapshot.exists()) {
        Log.d(TAG, "Current data: " + snapshot.getData());
    } else {
        Log.d(TAG, "Current data: null");
      }
   }
 });

引用自https://firebase.google.com/docs/firestore/query-data/listen

希望对你有帮助

编辑 收听全集:

    db.collection("cities")
    .addSnapshotListener(new 
     EventListener<QuerySnapshot>() {
        @Override
        public void onEvent(@Nullable QuerySnapshot value,
                            @Nullable FirebaseFirestoreException e) 
           {
            if (e != null) {
                Log.w(TAG, "Listen failed.", e);
                return;
            }

            List<String> cities = new ArrayList<>();
            for (QueryDocumentSnapshot doc : value) {
                if (doc.get("name") != null) {
                    cities.add(doc.getString("name"));
                }
            }
            Log.d(TAG, "Current cites in CA: " + cities);
        }
      });

这肯定会收听整个系列。 参考:https://stackoverflow.com/a/48608816/8714139

编辑这是你将如何获得你的价值观

        Map<Character,List<QueryDocumentSnapshot>> dataDoc = new HashMap<>();
            for (QueryDocumentSnapshot document : value) {
                char letter = getFirstLetter(document.getString("full_name"));
                List<QueryDocumentSnapshot> l = dataDoc.get(letter);
                if (l == null) {
                    l = new ArrayList<>();
                    l.add(document);
                    dataDoc.put(letter, l);
                } else {
                    l.add(document);
                }
            }

【讨论】:

  • 感谢您的回答。我知道我可以收听特定的文档,但是如果将新文档添加到集合中并没有多大帮助。在那种情况下,我想将其添加到回收视图中(即使我必须将其全部删除并重新设置)。如果可以收听集合(而不是文档),我可以删除 RV 并重新设置。我确定有办法做到这一点,但我似乎无法弄清楚。
  • 哦,看起来很棒!正如我从其他主题中了解到的那样,为了更新 RV,我需要更改 dataDoc。我将它移动为主要片段的一个字段。现在我正在尝试更新它。但是QuerySnapshot 是什么?如何将其转换为QueryDocumentSnapshot?更新了我的问题,这样会更清楚。
  • 如果你检查我编辑的代码,你会看到: List city = new ArrayList(); for (QueryDocumentSnapshot doc : value) { if (doc.get("name") != null) { urban.add(doc.getString("name")); } } 值是 QuerySnapshot,你必须循环。
猜你喜欢
  • 1970-01-01
  • 2020-10-27
  • 2012-03-30
  • 2020-05-18
  • 2023-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-26
相关资源
最近更新 更多