#flutter #stream #riverpod
#flutter #поток #riverpod
Вопрос:
Я хочу прослушивать коллекцию firebase в режиме реального времени с помощью StreamProvider из Riverpod и считывать значения у другого провайдера, но ничего из того, что я пробовал, не работает.
/// StreamProvider
final firstProvider = StreamProvider.autoDispose((ref) async* {
final stream = FirebaseFirestore.instance
.collection('someCollection')
.orderBy('timestamp', descending: true)
.snapshots()
.distinct();
await for (final value in stream) {
print('value: $value');
yield value;
}
}
final secondProvider = FutureProvider.autoDispose((ref) async {
final first_provider = await ref.watch(firstProvider);
print(first_provider .whenData((value) => value.docChanges.length));
...
});
Я думал, что при использовании docChanges
я получу только новые данные, но вместо этого они дублируются при каждой перестройке.
Есть идеи относительно того, что я делаю неправильно?
Ответ №1:
С вашими провайдерами все в порядке. Однако docChanges
возвращает массив документов, измененных с момента предыдущего снимка, и, если это первый снимок, будет содержать все документы.
Вы используете autoDispose
модификатор для своих провайдеров. Итак, если виджет (или другой провайдер и т.д.), С которого вы читаете своих провайдеров, удален, ваши провайдеры также будут удалены. Это приведет к новому чтению из вашей базы данных, что приведет к возврату всех документов docChanges
.
Попробуйте удалить autoDispose
модификатор и посмотреть, что произойдет.
Комментарии:
1. Привет, спасибо за ваш ответ! Да, я действительно уже сделал это и решил проблему, хотя я не думаю, что это правильный подход. С помощью модификатора .autodispose у нас есть новое свойство ref.mantainstate, которое по умолчанию равно false . Согласно документам riverpod.dev/docs/concepts/modifiers/auto_dispose , установив для этого значение true, мы не будем запускать какие-либо другие запросы при изменении экранов / перестроении виджетов.
2. Рад, что вы смогли это решить. Я бы сказал, что подход зависит от варианта использования. Если maintainState работает для вас здесь, я бы сказал, отлично, обычно лучше использовать autoDispose, если вы можете. Хотя, безусловно, бывают случаи, когда его не стоит использовать.
Ответ №2:
Если у кого-то такая же проблема, я решил ее, установив дополнительное свойство, maintainState
, которое autoDispose
предоставляет модификатор.
final firstProvider = StreamProvider.autoDispose((ref) async* {
final stream = FirebaseFirestore.instance
.collection('someCollection')
.orderBy('timestamp', descending: true)
.snapshots()
.distinct();
ref.mantainstate = true;
await for (final value in stream) {
print('value: $value');
yield value;
}
}
Комментарии:
1. Поскольку это решило вашу проблему, вы должны пометить это как принятый ответ.