android - 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
器并缓存最后的数据,这对于几乎应用程序来说根本不方便。
解决方案
确保当 UserAmessageId
从服务器中删除消息时,消息 (Messages/UserA/UserB/messageId
和Messages/UserB/UserA/messageId
) 的两个用户副本都被删除。
在您的问题代码中,您正在执行查询,而不是简单的数据库查找。当您使用任何orderBy
函数时,您总是会得到一个“存在”的快照对象,但您必须查看返回的快照的子对象,因为那是存储查询结果的地方。
总而言之,通过查询的结果,
- 用于
snapshot.hasChildren()
检查任何结果, - 用于
snapshot.getChildrenCount()
计算结果的数量,以及 - 用于使用
snapshot.getChildren()
迭代器遍历结果。
在您的情况下,可以通过不在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() {
推荐阅读
- python - Google ReCaptcha 3 总是返回 0.9 的分数
- php - 如何在php中用星号替换手机号码,除了最后4位数字
- javascript - 如何在多个 Dropzone 上显示来自服务器的文件
- amazon-web-services - 如何在不使用 AD SAML 2.0 的 aws cognito 中的托管 ui 的情况下获取 jwt 令牌
- flutter - 升级到 Flutter 1.7.8+hotfix.3 时无法编译
- c++ - 这个函数被调用了多少次?
- vb.net - Visual Basic,查找和替换文本
- arrays - 尝试从数组中删除 1 位并在 Ruby 中返回数组
- java - 在文件中保存和加载列表
- java - 显示 DialogFragment 时隐藏系统导航栏