Используйте цикл для пропуска элемента списка в построителе потоков

#flutter #for-loop

Вопрос:

Я получаю список пользователей с потоком, и мне нужно игнорировать текущего пользователя. Я сделал это однажды с Будущим списком, но в StreamBuilder при определении списка документов появляется ошибка.

Итак, вот что работает (Будущее):

 Future<List<Users>> _getUsers() async {
    Firestore db = Firestore.instance;

    QuerySnapshot querySnapshot = await db
        .collection('users')
        .getDocuments();

    List<Users> usersList = [];
    for (DocumentSnapshot item in querySnapshot.documents) {
      var data = item.data;
      if (data["id"] == _userId) continue;

      Users user = Users();
      user.name = data["name"];
      user.username = data["username"];
      user.id = data["id"];

      usersList.add(user);
    }

    return usersList;
  }
 

И это не работает (поток):

 startConnecting() {
    return Expanded(
      child: StreamBuilder(
        stream:Firestore.instance.collection('users').snapshots(),
        builder: (context, snapshot) {
          if (!snapshot.hasData) {
            return Center(
              child: Text(
                "Nothing."
                ),
              ),
            );
          }
          return ListView.builder(
            padding: EdgeInsets.only(top: 10),
            scrollDirection: Axis.vertical,
            itemCount: snapshot.data.documents.length,
            itemBuilder: (context, index) =>
                _buildListUsers(context, snapshot.data.documents[index]),
          );
        },
      ),
    );
  }

Widget _buildListUsers(BuildContext context, DocumentSnapshot document) {
    List<Users> usersList = [];
    for (DocumentSnapshot item in document) {
 

В этом последнем «документе»появляется сообщение об ошибке:» Тип «DocumentSnapshot», используемый в цикле «для», должен быть итеративным».

       var data = item.data;
      if (data["id"] == _userId) continue;

      Users user = Users();
      user.name = document["name"];
      user.username = document["username"];
      user.id = document["id"];

      usersList.add(user);

      return ListTile(
        ...
      );
    }
  }
 

Я искал эту ошибку, но не нашел ничего подобного. Должно быть, это что-то простое, чего мне не хватает.

Комментарии:

1. Не делай этого: stream:Firestore.instance.collection('users').snapshots() . Внимательно прочитайте второй и третий абзацы документов о StreamBuilder. Они объясняют, почему то, что вы делаете, сломано.

Ответ №1:

Вам не нужно просматривать снимок DocumentSnapshot, потому что, как уже говорилось, это не повторяющийся объект, а один документ. Так что измените это:

 Widget _buildListUsers(BuildContext context, DocumentSnapshot document) {
    List<Users> usersList = [];
    for (DocumentSnapshot item in document) {
 

К этому:

 Widget _buildListUsers(BuildContext context, DocumentSnapshot document) {
    List<Users> usersList = [];
    //for (DocumentSnapshot item in document) { ==> comment out this for loop
  var data = document.data;
    //keep your logic here as it

    //remove the closing curly brace at the end, because there is no more for loop.
 

Чтобы ответить на ваш второй вопрос в комментарии, сделайте это:

 if (data["id"] != _userId) {

      Users user = Users();
      user.name = data["name"];
      user.username = data["username"];
      user.id = data["id"];

      usersList.add(user);
    }
 

Комментарии:

1. Я сделал это, но «элемент» становится неопределенным, и невозможно использовать оператор continue вне цикла или переключателя

2. Также измените его на это: var data = document.data; . Вам больше не нужен элемент, потому что нет цикла for.

3. Понял. Есть ли какая-то альтернатива для оператора continue?

4. Решена ли проблема? Я также не вижу продолжения в вашем построителе потоков. Вы всегда можете использовать a return для остановки процесса вместо использования uid ==uid continue => > uid!=uid return .

5. Нет. Я имею в виду эту часть if (data["id"] == _userId) continue; . Я хочу, чтобы текущий пользователь был пропущен при создании списка и не останавливал процесс. Есть ли способ сделать это без использования continue?