【问题标题】:Flutter-Firebase await return after stream.listen() finish在 stream.listen() 完成后 Flutter-Firebase 等待返回
【发布时间】:2021-09-17 12:01:46
【问题描述】:

Flutter Stream 问题 我正在尝试通过geohash 过滤我的数据库查询,所以我使用的是 Geoflutterfire,它返回一个 Stream。我尝试将来自Stream<List<>> 中的每个DocumentSnapshot 的数据转换为List。它有效,但问题是return 发生在stream.listen() 的实际完成之前。如何延迟 return 以返回 stream.listen 结果? 我尝试使用await for(...),但它出错了。

import 'dart:async';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:geoflutterfire/geoflutterfire.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:uerto/models/index.dart';

class SearchApi {
  const SearchApi({required FirebaseAuth auth, required FirebaseFirestore firestore, required FirebaseStorage storage, required Geoflutterfire geo})
      : _auth = auth,
        _firestore = firestore,
        _storage = storage,
        _geo = geo;

  final FirebaseAuth _auth;
  final FirebaseFirestore _firestore;
  final FirebaseStorage _storage;
  final Geoflutterfire _geo;

  Future<List<AppClient>> getClientList(LatLng location, String category, String subCategory, double radius, int limit) async{

    final List<AppClient> newResult = <AppClient>[];
    final GeoFirePoint center = _geo.point(latitude: location.latitude, longitude: location.longitude);
    final Query<Map<String, dynamic>> collectionReference = _firestore.collection('London$category/$subCategory/UID').limit(limit);
    const String field = 'position';
    final Stream<List<DocumentSnapshot<Map<String, dynamic>>>> stream = _geo.collection(collectionRef: collectionReference).within(center: center, radius: radius, field: field);
    // ignore: always_specify_types
    stream.listen((List<DocumentSnapshot> documentList) {
      // ignore: always_specify_types, avoid_function_literals_in_foreach_calls
      documentList.forEach((DocumentSnapshot document) async {
        ///print(document.data());
        final SearchUid searchUid = SearchUid.fromJson(document.data());
        //print(searchUid.uid);
        final DocumentSnapshot<Map<String, dynamic>> client = await _firestore.collection('clients').doc(searchUid.uid).get();
        final AppClient clientData = AppClient.fromJson(client.data());
        print(clientData);
        newResult.add(clientData);
      });
    });
    await for(List<DocumentSnapshot> documentList in stream){
      return newResult;
    }

  }
}

【问题讨论】:

  • 您想只返回流中的第一个结果吗?
  • @ChetanGoyal 是的,完全正确
  • 好的。我现在给出一个合适的答案。
  • 感谢您的宝贵时间!
  • 没问题。我已经发布了答案。如果您在使用它时遇到任何其他问题,请告诉我。

标签: flutter dart redux google-cloud-firestore flutter-dependencies


【解决方案1】:

因此,您可以尝试在流后使用 .onDone。因此,如果流结束,onDone 块将运行。

 stream.listen((List<DocumentSnapshot> documentList) {

}).onDone((){
 //run here
});

【讨论】:

  • 还是一样的错误
【解决方案2】:

您无需侦听即可仅从流中获取首次数据。

初始化流后,执行以下操作:

List<DocumentSnapshot> documentList = await stream.first;
// Do your operations here
return newResult;

【讨论】:

  • 好吧,我用你的代码更改了我的代码,但仍然是同样的问题
  • @FLTY 我已经编辑了我的答案。还是不行吗?
  • 不,它也不起作用..在你告诉我之前我已经添加了等待(导致弹出错误)..
  • 你能显示你收到的错误吗?
【解决方案3】:

@ChetanGoyal 如您所见,这不是错误。它跳过第 33-41 行(这是异步的和等待的)的事实很奇怪......你可以看到返回的打印是空的,并且在第 39 行的打印之前发生。

猜你喜欢
  • 2013-03-22
  • 2016-09-10
  • 2020-02-22
  • 2019-08-01
  • 1970-01-01
  • 2020-07-02
  • 2016-09-15
  • 2021-11-13
相关资源
最近更新 更多