首页 > 解决方案 > Firebase 获取错误数据

问题描述

我正在开发一个聊天应用程序并将 firebase 用作后端服务。我snapshot.exists()用来检查孩子是否存在并做一些事情。true但是即使那个孩子不存在,Firebase 也会返回。示例:我有 2 个用户 A 和 B,用户 A 向用户 B 发送消息,当用户 B 收到该消息并检查该消息是否存在时,Firebase 会返回true。然后用户 B 关闭应用程序,用户 A 删除数据库上的消息,用户 B 重新启动应用程序并再次检查,但true即使用户 A 删除了消息,它仍然返回。

P/s:我正在使用持久模式

这是数据库结构

----Messages
    |---UserA
    |------UserB
    |---------MessageId
    |---UserB
    |------UserA
    |---------MessageId  

检查存在的代码(在用户 B 设备上运行)

             ROOT_REF.child("Messages").child("UserA").child(userB_Id).orderByKey().equalTo(messageId)
.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                if (dataSnapshot.exists()){
                    //do stuff
                }else {

                }
            }

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

            }
        });


更新

我将代码更改为

ROOT_REF.child("Messages").child("UserA").child(userB_Id).child(messageId)
.addListenerForSingleValueEvent(new ValueEventListener() {});


但即使我从数据库中删除它仍然有数据

更新 2

也试过这段代码,但它仍然返回数据并且快照仍然存在

ROOT_REF.child("Messages").child("UserA").child(userB_Id).child(messageId).keepSynced(true);

ROOT_REF.child("Messages").child("UserA").child(userB_Id).child(messageId)
.addListenerForSingleValueEvent(new ValueEventListener() {

//after do stuff 

ROOT_REF.child("Messages").child("UserA").child(userB_Id).child(messageId).keepSynced(false);

});

现在我仍然卡住了,但我使用的是双倍查询的临时解决方案,第一个查询将无法使用,我们将从第二个查询中获取数据

ROOT_REF.child("Messages").child("UserA").child(userB_Id).child(messageId)
.addListenerForSingleValueEvent(new ValueEventListener() {

// dont use the first one

 ROOT_REF.child("Messages").child("UserA").child(userB_Id).child(messageId)
.addListenerForSingleValueEvent(new ValueEventListener() {
//get data from the second one
});

});

最终更新:如果我想在我的应用程序中使用该数据库结构检查其他节点上的数据,这可能是不可能的。为此,我需要keepsynced在节点上附加或添加一个侦听Messsages器并缓存最后的数据,这对于几乎应用程序来说根本不方便。

标签: androidfirebase-realtime-database

解决方案


确保当 UserAmessageId从服务器中删除消息时,消息 (Messages/UserA/UserB/messageIdMessages/UserB/UserA/messageId) 的两个用户副本都被删除。

在您的问题代码中,您正在执行查询,而不是简单的数据库查找。当您使用任何orderBy函数时,您总是会得到一个“存在”的快照对象,但您必须查看返回的快照的子对象,因为那是存储查询结果的地方。

有关使用列表的文档

总而言之,通过查询的结果,

在您的情况下,可以通过不在orderByKey()此行上使用来避免(和优化)这个问题:

ROOT_REF.child("Messages").child("UserA").child(userB_Id).orderByKey().equalTo(messageId).addListenerForSingleValueEvent(new ValueEventListener() {

并将其简化为基本的数据库查找,snapshot.exists()在您的问题中可以按预期工作:

ROOT_REF.child("Messages").child("UserA").child(userB_Id).child(messageId).addListenerForSingleValueEvent(new ValueEventListener() {

推荐阅读