来自 firebase rtdb 的 streambuilder 是否会更新 list<User> 用户数据?

Does streambuilder from firebase rtdb will update list<User> user data?

目前我了解方法 streamBuilder 我可以获取更新的数据并添加到 List<User> users.

但是如果这个已经在List<User> users中添加的用户更新了数据,那么它可以在List<User> users中重复添加这个用户数据吗?

  1. 你能告诉我如何确认新的数据List<User> users是否已经有相同的userId,如果是,新的数据/userId将取代这个现有的userId?

  2. 如果用户从 Firebase rtdb 中删除,流将收到通知,因此将此用户从 List<User> users?

    中删除

这是一个例子,我担心的是因为流总是会向列表用户添加数据,但是如果这个用户从数据库中删除或者断开连接怎么办,如何从这个列表中删除这个用户?

    _streamSubscription = availableUserStream.onValue.listen((snap) {
      if (snap.snapshot.exists && snap.snapshot.value != null) {
        DataSnapshot snapshotData = snap.snapshot;
    
        for (var userSnapshot in snapshotData.children) {
          final data = Map<String, dynamic>.from(userSnapshot.value as Map);
    
          List<User> users = [];
    
          User newUser = User.fromJson(data);
    
          users.add(newUser);
          firebaseController.setUsers(users: users);
    
        }
      }
    });

所以我想在这里做一个双重确认,如果这个用户仍然存在于数据库中:

  User getRandomSenderUser({User asReceiverUser}) {
    if (availableSenderUsersList.isNotEmpty) {

      final random = Random();
      var i = random.nextInt(availableSenderUsersList.length);

      User randomUser = availableSenderUsersList[i];

      bool thisRandomUserIsAvailable; //TODO

我不知道如何进行这项检查,例如如果这个 randomerUser 不可用,那么我需要获取下一个 randomUser,那么它应该是一个循环?但是会减慢响应速度。

       updateSenderUserAvailableStatus(asReceiverUser:asReceiverUser,connectionUser: randomUser);
    
          return randomUser;
        } else {
          return null;
        }
      }



thank you!

更新:

这是示例代码,所以现在我明白流会将用户数据传递给 List<User> users,但以我的方式,总会有之前添加到此列表中但已从数据库中删除的用户,我的计划是使用 while loop 进行双重确认以在获取 randomUser 时删除不可用的用户,但这听起来不聪明而且我猜还是浪费时间....

      @override
      void initState() {
        _listenAvailableUsers();
    }

    _listenAvailableUsers() {
        var availableUserStream =
            FirebaseDatabase.instance.ref().child('/waitingList');
    
        _streamSubscription = availableUserStream.onValue.listen((snap) {
          if (snap.snapshot.exists && snap.snapshot.value != null) {
            DataSnapshot snapshotData = snap.snapshot;
    
            for (var userSnapshot in snapshotData.children) {
              final data = Map<String, dynamic>.from(userSnapshot.value as Map);
    
              List<User> users = [];
    
              User newUser = User.fromJson(data);
    
              users.add(newUser);
              firebaseController.setUsers(users: users);
    
    
            }
          }
        });
      }

这是我用来确认随机用户是否仍然存在于数据库中的方法:

 Future<User> getRandomSenderUser({User asReceiverUser}) async {
    if (availableSenderUsersList.isNotEmpty) {

      User randomUser;

      while (true) {
        final random = Random();
        var i = random.nextInt(availableSenderUsersList.length);

        randomUser = availableSenderUsersList[i];

        DatabaseEvent event = await databaseReference
            .child('/waitingList/${randomUser.userId}')
            .once();
        print('randomUser is ${randomUser.toString()}');
        if (event.snapshot.value != null) {
          break;
        }
      }

      await updateSenderUserAvailableStatus(
          asReceiverUser: asReceiverUser, connectionUser: randomUser);

      print('connectionUserId is $connectionUserId');
      return randomUser;
    } else {
      return null;
    }
  }

由于您正在侦听数据库中某个路径的 onValue,因此您获得的 DataSnapshot 将包含该路径的全部数据。当数据只有很小的变化时,服务器只会将更新发送给客户端,但 SDK 然后会将其与现有数据合并,并仍然会触发一个事件,其中包含路径上所有数据的快照。

由于您每次从流中获取事件时都从一个空列表 (List<User> users = [];) 开始,这意味着您每次都在重建所有用户,这对我来说似乎是正确的.