首页 > 解决方案 > firebase 实时数据库读取不存在的数据

问题描述

我们遇到了可能是 firebase 数据库中的一个主要错误,请参见下面的代码。下面的代码尝试为没有读取或写入权限的子“EXAMPLE”设置一个值。写入操作不会向数据库写入任何内容,并在日志中抛出错误“setValue at /EXAMPLE/VALUE failed: DatabaseError: Permission denied”,这是一件好事。

但是一个主要问题是随后的代码尝试读取子“EXAMPLE”的值,该代码实际上进入 ondatachange 方法并将值读取为“ONE”,而不是进入 onCancelled 方法以抛出权限错误,数据库中甚至不存在数据,并且子“EXAMPLE”没有读取或写入权限,因此fireabase如何声称读取甚至不存在的值。

myReftwo.child("EXAMPLE").child("VALUE").setValue("ONE");

myReftwo.child("EXAMPLE").child("VALUE").addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot)
    {

        Log.d("print", dataSnapshot.getValue().toString()  );


    }
    @Override
    public void onCancelled(DatabaseError databaseError)
    {
        Log.d("print",  databaseError.getMessage() );
    }
});

标签: androidfirebasefirebase-realtime-database

解决方案


在您共享的片段中,由于服务器拒绝,侦听器很可能在更新缓存之前从本地缓存中获取值。

当您添加侦听器时,Firebase 会尝试为您提供它期望节点立即具有的值。并且由于您调用addListenerForSingleValueEvent,它们会立即停止侦听该值。因此,您最终只能从本地缓存中看到陈旧的值,而永远不会从服务器中看到实际值(或缺少实际值)。

因此,您不应addListenerForSingleValueEvent在应用程序中同时使用磁盘持久性。在相同的场景中使用addValueEventListener会导致两次调用onDataChange:第一个调用来自本地缓存的值,第二个调用来自服务器的正确快照。

有关这些如何工作以及为什么它们不会导致您想要的行为的更长答案,请参阅:Firebase Offline Capabilities 和 addListenerForSingleValueEvent


推荐阅读