Обновление данных Firestore автоматическое обновление страницы

# #flutter #google-cloud-firestore

Вопрос:

Я использую listen() для получения данных из Firestore. Я также использую setData и merge: true обновляю данные в Firestore. Когда в магазине Firestore появится обновление, оно автоматически обновит всю страницу. Как я могу помешать этому сделать это? Я хочу, чтобы он изменил значение, но не обновлял страницу. Возможно ли это? Любая документация или пример кода приветствуются. Заранее спасибо.

Обновить

Это мой DropDownButton :

 Row(
          mainAxisSize: MainAxisSize.min,
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            DropdownButton(
              items: routeName.map((value) {
                return DropdownMenuItem<String>(
                  value: value,
                  child: new Text(value),
                );
              }).toList(),
              underline: SizedBox(height: 0,),
              onChanged: (value) => setState((){
                selectedItem = value;
                polylineCoordinates.clear();
                getRoute();
              }),
              hint: new Text ("Select a Route"),
              value: selectedItem,
            )
          ],
        ),),
 

Вот где я добавляю значение в DropDownButton :

 List <String> routeName = [];
    
Future <void> getRouteName() async{
        Firestore.instance.collection('routes').snapshots().listen((RouteData) async {
          routeName.clear();
          if(RouteData.documents.isNotEmpty){
            for (int i = 0; i < RouteData.documents.length; i  ){
              if(i == 0){
                routeName.add("No Route");
              }
              routeName.add(RouteData.documents[i].documentID);
            }
          }
          setState(() {
          });
        });
      }
 

Это мой initState()

 @override
  void initState(){
    geoService.getCurrentLocation().listen((position){
      centerScreen(position);
    });
    geoService.getCurrentLocation().listen((position) {
      _addGeoPoint(position);
    });
    getMarker();
    getRouteName();
    retrieveRoute();
    super.initState();
  }
 

Вот где все идет не так:

  Future <void> getRoute() async{
    if (selectedItem == "No Route"){
      var user = await FirebaseAuth.instance.currentUser();
      Firestore.instance.collection('user').document(user.email).setData(
          {"Route": "No Route"}, merge: true);
    }
    var user = await FirebaseAuth.instance.currentUser();
    Firestore.instance.collection('user').document(user.email).setData(
        {"Route": selectedItem}, merge: true);
  }
 

Потому что я хочу , чтобы он обновлялся в Firestore всякий раз, когда я обновляю значение в DropDownButton , но после обновления он обновит мою страницу, и я не хочу, чтобы он обновлял всю страницу. Я просто хочу, чтобы он сохранялся в Firestore и обновлялся в DropDownButton единственном.

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

1. Можете ли вы поделиться своим кодом, который не работает должным образом?

Ответ №1:

Если вы хотите прослушать поток только один раз, вы можете использовать первый оператор в нем:

 Firestore.instance.collection('routes').snapshots().first.then(() => {
  // this will be called juste once
});
 

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

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

2. Что делать, если вы удалите свое состояние настройки из обратного вызова прослушивания?

3. Пытаюсь сделать то же самое. Появляется сообщение об ошибке, в котором говорится: «В поддереве есть несколько героев, у которых один и тот же тег». Это связано с этим?

4. Нашел это в Интернете. Это не имеет отношения к данной теме. Это была моя кнопка плавающего действия, которая вызывает это.

5. Выяснил проблему. Обновление страницы, потому что в моем документе много полей, когда есть изменения, он обновит страницу. Я создал новую коллекцию для их хранения, и я могу внести некоторые изменения, не обновляя страницу. Также спасибо за помощь. Спасибо.

Ответ №2:

Проблема кроется в вашем getRouteName методе.

 Future <void> getRouteName() async{
    Firestore.instance.collection('routes').snapshots().listen((RouteData) async {
      routeName.clear();
      if(RouteData.documents.isNotEmpty){
        for (int i = 0; i < RouteData.documents.length; i  ){
          if(i == 0){
            routeName.add("No Route");
          }
          routeName.add(RouteData.documents[i].documentID);
        }
      }
      setState(() {
      });
    });
  }
}
 

Каждый раз , когда вы звоните setState , это приведет к перекраске пользовательского интерфейса. Поскольку вы используете listen , чтобы вас вызывали для любых изменений routes , и вызываете setState() каждое такое изменение, любое изменение routes будет перекрашивать пользовательский интерфейс.

Если вы не хотите полностью перекрашивать пользовательский интерфейс, удалите вызов setState() . Если вы хотите перекрасить пользовательский интерфейс только в определенных условиях, перенесите вызов setState() в эти условия.

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

1. После удаления setState он все равно перезагрузится, когда я изменю значение в Firestore.

2. Выяснил проблему. Обновление страницы, потому что в моем документе много полей, когда есть изменения, он обновит страницу. Я создал новую коллекцию для их хранения, и я могу внести некоторые изменения, не обновляя страницу. Также спасибо за помощь. Спасибо.