#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?