Чрезмерное чтение Flutter Firestore

Я создаю приложение, чтобы показать последнюю цену на топливо для пользователей, и я использую прослушиватель моментальных снимков в своей базе данных Firebase Firestore, и, насколько я понимаю, он должен создавать 1 чтение для каждого пользователя только при обновлении базы данных... Я установите его на 1 устройство и получите 33 чтения для этого устройства!

Код, который подключается к Firebase:

    StreamBuilder<DocumentSnapshot>(
                                    stream: FirebaseFirestore.instance
                                        .collection('global')
                                        .doc('inland')
                                        .snapshots(),
                                    builder: (context, snapshot) {
                                      if (!snapshot.hasData) {
                                        return Text("Loading...",
                                            style: TextStyle(
                                                color: Colors.black,
                                                fontWeight: FontWeight.w700,
                                                fontSize: 34.0));
                                      }
                                      if (snapshot.hasError) {
                                        return Text("Error",
                                            style: TextStyle(
                                                color: Colors.black,
                                                fontWeight: FontWeight.w700,
                                                fontSize: 34.0));
                                      }
                                      if (snapshot.connectionState ==
                                          ConnectionState.waiting) {
                                        return Text("Loading...",
                                            style: TextStyle(
                                                color: Colors.black,
                                                fontWeight: FontWeight.w700,
                                                fontSize: 34.0));
                                      } else {
                                        Map<String, dynamic> document =
                                            snapshot.data.data();
                                        return Text("R " + document['95'],
                                            style: TextStyle(
                                                color: Colors.black,
                                                fontWeight: FontWeight.w700,
                                                fontSize: 34.0));
                                      }

Он находится в AnimatedContainer, но, насколько я понимаю, приложение показывает цену из кеша, когда она не меняется в базе данных, поэтому это не должно иметь значения.

Я что-то неправильно понимаю? И есть ли способ исправить это?

Интеграция Angular - Firebase Analytics
Интеграция Angular - Firebase Analytics
Узнайте, как настроить Firebase Analytics и отслеживать поведение пользователей в вашем приложении Angular.
1
0
1 054
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы создаете поток каждый раз, когда флаттер вызывает метод build этого виджета, что может быть много раз. Метод сборки должен быть чистым, без каких-либо побочных эффектов*. Другими словами, вы не должны создавать дорогостоящие объекты, такие как поток, внутри метода сборки. Вы должны создать объект снаружи и передать его виджету.

Чтобы решить эту проблему, вы можете создать виджет с состоянием, а внутри метода initState вы должны инициализировать свой поток, а затем передать его в StreamBuilder.

class StreamBuilderExample extends StatefulWidget {
  @override
  _StreamBuilderExampleState createState() => _StreamBuilderExampleState();
}

class _StreamBuilderExampleState extends State<StreamBuilderExample> {
  Stream<DocumentSnapshot> firestoreStream;
  @override
  void initState() {
    firestoreStream = FirebaseFirestore.instance.collection('global').doc('inland').snapshots();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return StreamBuilder(
      stream: firestoreStream,
      builder: (context, snapshot) {
        // your code goes here
      },
    );
  }
}

Что касается последнего фрагмента вашего вопроса, Firestore будет читать из кеша только в том случае, если вы сообщите ему об этом или если нет подключения к Интернету. Каждый раз, когда вы инициируете поток или получаете документы, Firestore сначала обращается к серверу и снова перечитывает документы. Хотя, когда поток запущен, Firestore будет обновляться только при внесении изменений в документы вашего запроса. Но, как упоминалось ранее, вы получаете много прочтений, потому что ваш поток воссоздается каждый раз, когда создается виджет (это также может быть вызвано горячей перезагрузкой или просто сохранением файла).

Другие вопросы по теме