首页 > 解决方案 > 即使 Firebase 安全规则设置为 true,也无法从节点读取数据

问题描述

我有一个带有主题节点的 firebase 数据库,其中包含各种主题。当我尝试在此节点上应用读取规则时,我能够读取 firebase 安全规则模拟器中的值,但不能读取我的实际应用程序中的值。但是,如果我将规则应用于父节点本身,我就可以获取该值。

这是我的数据库: 在此处输入图像描述

以下是我的 Firebase 安全规则:

  {
  "rules": {
    "users":{
      "$user_id":{
        ".read": "auth != null && !root.child('blocked/'+$user_id+'/'+auth.uid).exists()",
        ".write": "$user_id === auth.uid"
      }
    },
    "topics":{
      //".read": "true",
      "$topic_id":{
        //restricting blocked users from reading the topcis
        ".read": "true",
        ".write": "auth != null"
      },
    }
  }
}

现在,如果我在父节点上取消注释此“.read”规则,我可以读取,但当我使用通配符应用它时无法读取。我也可以很好地写入主题节点。

这是我试图从 firebase 数据库访问数据的功能。

public void loadTopics() {
        //Load topics for the first time
        createTopicFab.show();
        Query topicQuery = FirebaseDatabase.getInstance().getReference()
                .child(FirebaseValues.TOPICS_TABLE).limitToLast(TOTAL_ITEM_EACH_LOAD).orderByChild("createdTimestamp");
        itemPos = 0;
        topics.clear();
        topicIds.clear();
        topicQuery.addChildEventListener(new ChildEventListener() {


            @Override
            public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {

                // Add the values in the topics list and notify the adapter
                loadingLayout.setVisibility(View.GONE);
                Topics topic = dataSnapshot.getValue(Topics.class);
                Log.d(TAG, "loadTopics(), Topic: " + topic.getText());
                topics.add(0, topic);
                if (itemPos++ == 0) {
                    //first key
                    lastKey = String.valueOf(dataSnapshot.getKey());
                }
                topicIds.add(0, dataSnapshot.getKey());
                topicsListAdapter.notifyDataSetChanged();
                swipeRefTopic.setRefreshing(false);
            }

            @Override
            public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {

            }

            @Override
            public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {
                // remove the values in the topics list and notify the adapter
            }

            @Override
            public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {

            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });
    }

标签: androidfirebasefirebase-realtime-databasefirebase-security

解决方案


这是您的基本查询:

Query topicQuery = FirebaseDatabase.getInstance().getReference()
    .child(FirebaseValues.TOPICS_TABLE)

我认为这FirebaseValues.TOPIC_TABLE是“主题”。此查询无法读取 /topics 处的子项,因为您尚未在该位置授予读取权限。正如您所观察到的,当您授予对 /topics 的访问权限时,它将起作用。查询的位置是最重要的——孩子的许可在案​​件中并不重要。安全规则不会为您“过滤”该位置下的孩子。阅读有关“安全规则不是过滤器”的文档。


推荐阅读