android 如何在Firestore Firebase中跳过初始数据并只触发新的更新?

hl0ma9xz  于 2023-02-02  发布在  Android
关注(0)|答案(4)|浏览(84)

我到处都找不到运气。我想查询Firestore以获得所有用户WHERE类型是管理员。

SELECT * FROM users WHERE type=admin

但是只有total属性改变时。如果我使用:

users.whereEqualTo("type", "admin").addSnapshotListener(new EventListener<QuerySnapshot>() {
    @Override
    public void onEvent(@Nullable QuerySnapshot snapshots, @Nullable FirebaseFirestoreException e) {
        for (DocumentChange dc : snapshots.getDocumentChanges()) {
            switch (dc.getType()) {
                case ADDED:
                    //Not trigger
                    break;
                case MODIFIED:
                    //Trigger
                    break;
                case REMOVED:
                    //
                    break;
            }
        }
    }
});

案例ADDED是我第一次查询时触发的,当total发生变化时,case MODIFIED再次触发(这是我想要的),我只想要变化,而不是所有的初始数据,我不需要它,如何获得它?
请帮助我,是我的项目的最后一部分。如何跳过是case ADDED

ccrfmcuu

ccrfmcuu1#

当您使用Firestore Query的addSnapshotListener()方法监听Cloud Firestore中的实时更改时,它会:
开始侦听此查询。
这基本上意味着第一次附加侦听器时,您将获得与该特定查询对应的所有文档。此外,每次文档中的属性更改时,您都会收到相应的更改通知。显然,只有侦听器保持活动状态且未被删除时,才会发生这种情况。
不幸的是,Firestore监听器不能以这种方式工作,所以您不能跳过“case ADDED”,而可以做的是在每个用户对象下添加一个Date属性(**this**是您可以添加它的方法),并根据这个新属性查询客户端上的数据库,以查找自上次以来发生更改的所有文档。
根据尼克·卡多佐的评论,对于未来可能会问为什么会发生这种行为的游客,是因为他在评论中提到的原因。我也建议看看道格·史蒂文森的回答,从这篇文章,以更好地理解。

kjthegm6

kjthegm62#

有一个选项可用于检查querySnapshot是否来自缓存,更改是否返回false

if(querySnapshot.getMetadata().isFromCache()) return
c2e8gylq

c2e8gylq3#

下面是一个适合我的解决方案:使用

AtomicBoolean isFirstListener = new AtomicBoolean(true);

然后是事件方法

if (isFirstListener.get()) {
                    isFirstListener.set(false);
                    //TODO Handle the entire list. 
                    return;
                }

下面是我的项目中的示例代码:

final AtomicBoolean isFirstListener = new AtomicBoolean(true);
 mDb.collection("conversation_log").document(room_id).collection("messages").orderBy("sent_at")
    .addSnapshotListener(new EventListener<QuerySnapshot>() {
        @Override
        public void onEvent(@Nullable QuerySnapshot value2, @Nullable FirebaseFirestoreException e) {
        if (isFirstListener.get()) {
            isFirstListener.set(false);
            //TODO Handle the entire list.
            return;
        }
    }
});

参考:answer

chhqkbe1

chhqkbe14#

已找到此给定用例的变通方法,可以跳过初始数据而仅获取更新。变通方法是在结构中包括服务器时间戳,并构建查询以仅获取时间戳大于当前时间的数据。

val ref = db.collection("Messages").document("Client_ID")
        .collection("Private")
        .orderBy("timestamp")
        .whereGreaterThan("timestamp",Calendar.getInstance().time)

//Add snapshot listener
ref.addSnapshotListener { snapshot , e ->
            if (snapshot != null) {
                Log.d("TAG", "Current data: ${snapshot.documents.size}")
                for(document in snapshot.documents){
                    Log.e("Document Data",document.data.toString())
                }
            }
        }

因此,查询在初始构建时不会返回任何数据,但会监听文档的更改。一旦文档的时间戳发生更改,您就会收到有关该更改的通知。然后,您可以检查列表中是否存在该数据(如果您正在查找修改,或者是否添加了新文档)
当您写入任何更改时,只需更新文档的时间戳。如下图所示:

val message = hashMapOf<String,Any>(
        "timestamp" to FieldValue.serverTimestamp(),
        "id" to userId,
        "data" to data,
    )
db.collection("Messages").document("Client_ID")
        .collection("Private")
        .document().set(message)

相关问题