Flutter:需要触发/重新运行StreamProvider QuerySnapshot流

时间:2020-07-24 12:43:16

标签: flutter google-cloud-firestore flutter-provider

使用Flutter / Dart,提供者:^ 4.1.2 / cloud_firestore:^ 0.13.6。

main.dart中的提供程序设置:

//companyId will be saved in this changeNotifier class with a `notifyListeners();`
ChangeNotifierProvider<SharedPreferencesData>(
      create: (context) => SharedPreferencesData(), 
    ),

//when companyId is saved above, it'll trigger the ChangeNotifierProxyProvider
    ChangeNotifierProxyProvider<SharedPreferencesData, DatabaseService>(
  create: (_) => DatabaseService(),
  update: (_, sharedPreferencesData, databaseService) {
    databaseService.sPData = sharedPreferencesData;
    return databaseService;
  },
    ),
  ],
  child: Builder(builder: (BuildContext bCtx) {
    return MultiProvider(
      providers: [

//This StreamProvier should update when DatabaseService ChangeNotifierProxyProvider is triggered:
    StreamProvider<List<Location>>.value(
      value: Provider.of<DatabaseService>(bCtx).getLocations,
      initialData: List(),
    ),

sharedPreferences文件:

class SharedPreferencesData with ChangeNotifier {
  var _sharedPreferencesData = SharedPreferences(
    companyId: '',
  );
  void setSharedPrefDataCompanyId(String companyId) {
    final newSharedPreferences = SharedPreferences(
      companyId: companyId,
    );
    _sharedPreferencesData = newSharedPreferences;
    notifyListeners();
  }

用于配置流的数据库文件:

  Stream<List<Location>> get getLocations {
//companyId won't be ready when the app runs at first
    var companyId = sPData.getSharedPreferencesData().companyId;
    return locationsCollection
        .where('companyId', isEqualTo: companyId)
        .snapshots()
        .map(_locationsListFromSnapshot); ===> this method to convert the QuerySnapshot to List<Location>
  }

在新的屏幕/文件中收听StreamProvider:

final locations = Provider.of<List<Location>>(context);

运行该应用程序时,companyId将为空,因此Locations流得到更新,但返回空List。然后将分配字符串companyId,Stream<List<Location>>运行时不会再次运行ChangeNotifierProxyProvider<SharedPreferencesData, DatabaseService>。并因此使用更新的companyId获取正确的位置。

注意:我注意到只有当我完全停止main.dart然后运行main.dart但如果该应用程序已经在运行,并且按Run main.dart(不是Flutter Hot reload)时,才会发生上述行为, Stream 首先以一个空列表运行,但随后以某种方式被触发并以正确的companyId获取正确的位置。

  • 如何触发Stream (在添加companyId之后)?

  • 为什么当STOP / RUN ChangeNotifierProxyProvider<SharedPreferencesData, DatabaseService>不会触发位置信息流时,但是如果仅单击RUN,则会触发位置信息流并且应用程序可以正常工作。

  • STOP / RUN ...和(应用程序已在运行)=> RUN(不是热重装)有什么区别?以某种方式影响应用程序的逻辑行为。

0 个答案:

没有答案