使用 Flutter 访问 Firebase RTDB 中的嵌套节点

Accessing nested nodes in a Firebase RTDB, using Flutter

我有一个数据库,用于存储用户信息,例如他们的姓名和他们所有的朋友。数据库看起来像这样:

{
  "users": {
    "userID here": {
      "bio": "",
      "country": "",
      "dateOfBirth": "2022-04-13 17:49:45.906226",
      "emergencyContacts": {
        "mom": {
          "emailAdd": "mom@gmail.com",
          "name": "mom",
          "phoneNumber": "07492017492",
          "picUrl": "url here'"
        }
      },
      "friends": {
        "auto-generated ID (used push method)": {
          "country": "",
          "profilePicUrl": "url here",
          "userID": "userID here",
          "username": "newOne"
        }
      },
      "fullName": "name",
      "gender": "Female",
      "hobbies": "[]",
      "knownMH": "[]",
      "lastMessageTime": "2022-04-14 08:44:40.639944",      
  }
}

我想访问 "friends" 节点。在这样做的同时,我还想将数据存储在二维数组中。因此,每个子数组都将包含有关我们当前正在循环访问的用户及其朋友之一的数据。这应该发生,直到我们遍历所有用户的朋友,然后转到下一个用户。

也值得一提;我使用了推送方法来添加朋友,所以我得到了节点的随机分配密钥。

我使用了下面的方法,但它不起作用,它返回了错误的朋友列表并且没有遍历所有用户。请在下面找到我使用的代码(非常感谢任何帮助):

  void _retrieveAllFriendships() {
    final allUsersDb = FirebaseDatabase.instance.ref().child('users');
    _allUserssStream = allUsersDb.onValue.listen((event) {
      if (event.snapshot.exists) {
        final data = new Map<dynamic, dynamic>.from(
            event.snapshot.value as Map<dynamic, dynamic>);

        data.forEach((key, value) {
          allUsersDb.child(key).onValue.listen((event) {
            final acc = new Map<dynamic, dynamic>.from(
                event.snapshot.value as Map<dynamic, dynamic>);

            final username = acc['username'] as String;
            final profilePicUrl = acc['profilePicUrl'] as String;
            final country = acc['country'] as String;
            final userID = acc['userID'] as String;

            user = new FriendSuggestionModel(
              picture: profilePicUrl,
              name: username,
              location: country,
              userID: userID,
            );

            _friendshipStream = allUsersDb
                .child(userID)
                .child("friends")
                .onValue
                .listen((event) {
              if (event.snapshot.exists) {
                final data = new Map<dynamic, dynamic>.from(
                    event.snapshot.value as Map<dynamic, dynamic>);

                data.forEach((key, value) {
                  allUsersDb
                      .child(userID)
                      .child("friends")
                      .child(key)
                      .onValue
                      .listen((event) {
                    final friend = new Map<dynamic, dynamic>.from(
                        event.snapshot.value as Map<dynamic, dynamic>);

                    final username = friend['username'] as String;
                    final profilePicUrl = friend['profilePicUrl'] as String;
                    final country = friend['country'] as String;
                    final userID = friend['userID'] as String;

                    friendModel = new FriendSuggestionModel(
                        picture: profilePicUrl,
                        name: username,
                        location: country,
                        userID: userID);
                    List<FriendSuggestionModel> friendship = [
                      user,
                      friendModel
                    ];
                    allFriendships.add(friendship);

                    setState(() {
                      for (int i = 0; i < allFriendships.length; i++) {
                        print(
                            "${allFriendships[i][0].name} is friends with: ${allFriendships[i][1].name}");
                      }
                    });
                  });
                });
              }
            });
          });
        });
      }
    });
  }

当您将侦听器附加到 allUsersDb.onValue 该路径下的所有数据 已经存在于 event.snapshot 中并且您不需要更多的侦听器对于该数据。

如果您知道要访问的子快照的名称,可以通过 snapshot.child("friends") 获取。如果您不知道子快照的名称,可以使用 snapshot.children.forEach.

遍历所有子快照