Как слушать обновления Firebase в реальном времени во Flutter - PullRequest
0 голосов
/ 17 июня 2020

У меня есть поток, который читает пользовательские данные из firebase. Я запускаю его после входа в систему, работает отлично. Я показываю данные на панели приложений. Когда я обновляю firebase вручную, я хочу мгновенно видеть новую дату на панели приложений. Сначала я догадался, что с моей панелью приложений что-то не так, но потом заметил, что мой поток не запускается, когда я обновляю данные firebase. Вот мой фрагмент кода потока. Что мне не хватает?

static Future<User> userDataStream(userID) async {
    print("userDataStream");

    final databaseReference = Firestore.instance;
    User currentUser = User();

    await for (var snapshot in databaseReference
        .collection('users')
        .where('userID', isEqualTo: userID)
        .snapshots()) {
      currentUser.userName = snapshot.documents.first.data['userName'];
      currentUser.email = snapshot.documents.first.data['email'];
      currentUser.userID = snapshot.documents.first.data['userID'];
      currentUser.level = snapshot.documents.first.data['level'];
      currentUser.balance = snapshot.documents.first.data['balance'];

      print(currentUser.balance);

      return currentUser;
    }

    return currentUser;
  }

Ответы [ 2 ]

2 голосов
/ 17 июня 2020

Имеет значение, как вы используете этот поток. await for начинает слушать пользователя, затем вы выполняете в нем return currentUser; и нарушаете await for. Следовательно, он не может продолжать прослушивание потока в будущем.

Вместо return currentUser; внутри await for вы можете сделать что-то вроде setState((){this.renderedUser = currentUser;}), чтобы пользователь, пришедший с сервера, стал визуализированным. Если вы это сделаете, также добавьте if (!mounted) return; в await for, чтобы вы перестали его слушать, когда поймете, что находитесь на другом экране.

Лучшей альтернативой может быть использование виджета StreamBuilder.

1 голос
/ 17 июня 2020

Если вы запустите свой текущий код и внесете изменения в базу данных, оператор print должен быть запущен снова. Это потому, что snapshots уже прослушивает изменения в базе данных и вызывает ваш код, когда это происходит.

Проблема в том, что вы возвращаете Future<User>, и будущее может быть разрешено только (получить значение ) один раз. Если вы хотите вернуть данные в реальном времени, это будет Stream<User> (и обычно StreamBuilder вместо FutureBuilder для создания пользовательского интерфейса).

...