Flutter:在流中访问 SharedPreferences Provider / ChangeNotifier Class

Flutter: Access SharedPreferences Provider / ChangeNotifier in a Stream Class

我在 Whosebug 中四处寻找,但没能找到解决方案。 设想: 我有一个带有 ChangeNotifier Class 的 Flutter SharedPreferences Provider,它将使用当前登录的用户信息进行更新。

简化内容:

class SharedPreferences {
  final String userId;
  final String userName;

  SharedPreferences({
    @required this.userId,
    @required this.userName,
  });
}
class SharedPreferencesData with ChangeNotifier {
  var _sharedPreferencesData = SharedPreferences(
    userId: 'testUserId',
    userName: 'testUserName',
  );}

还有一个 database.dart 文件 Class 包含用于从快照获取 FireStore 流的 DataBaseServices:

class DatabaseService {
  final CollectionReference companiesProfilesCollection =
      Firestore.instance.collection('companiesProfiles');

  List<CompanyProfile> _companiesProfilesFromSnapshot(QuerySnapshot snapshot) {
    return snapshot.documents.map((doc) {
      return CompanyProfile(
        docId: doc.documentID,
        companyName: doc.data['companyName'] ?? '',
        maxLocationsNumber: doc.data['maxLocationsNumber'] ?? 0,
        maxUsersNumber: doc.data['maxUsersNumber'] ?? 0,
      );
    }).toList();
  }

  Stream<List<CompanyProfile>> get getCompaniesProfiles {
    return companiesProfilesCollection
        .where('userId', isEqualTo: _userIdFromProvider) 
        // My problem is above -----
        .snapshots()
        .map(_companiesProfilesFromSnapshot);
  }
}

我不想获取整个 Stream 数据,因为它对于其他 Stream 来说可能很大,我只想在 .where('userId', isEqualTo:_userIdFromProvider) 下传递 userID。

我还是个初学者,如果您能与我分享处理此问题的最佳方法,我将不胜感激。 谢谢!

*********** 通过添加以下内容重新编辑:************** 我正在尝试实现相同的场景,这是我的代码: 主文件:

return MultiProvider(
  providers: [
    ChangeNotifierProvider<SpData>(
      create: (context) => SpData(),
    ),
    ProxyProvider<SpData, DS>(
      create: (context) => DS(),
      update: (ctx, spData, previousDS) {
        print('ChangeNotifierProxyProvider RAN');
        previousDS.dbData = spData;
        return previousDS;
      },
    ),
  ],

SP 文件:

class SP {
  final String companyId;
  SP({
    @required this.companyId,
  });
}

class SpData with ChangeNotifier {
  var _sPData = SP(
    companyId: '',
  );
  void setCompanyId(String cpID) {
    final newSharedPreferences = SP(
      companyId: cpID,
    );
    _sPData = newSharedPreferences;
    print('_spData companyId:${_sPData.companyId}');
    notifyListeners();
  }

  String get getCompanyId {
    return _sPData.companyId;
  }
}

DS 文件:

class DS with ChangeNotifier {
  SpData dbData;
  void printCompanyId() {
    var companyId = dbData.getCompanyId;
    print('companyId from DataBase: $companyId');
  }
}

SpData dbData; inside Class DS 不更新。我已经添加了指纹来弄清楚什么是 运行ning 什么不是。当我 运行 我的代码时, main.dart 文件中的打印函数 print('ChangeNotifierProxyProvider RAN');没有 运行.

我错过了什么?为什么没有触发 ChangeNotifierProxyProvider 来更新 DS 文件中的 dbData?谢谢!

您可以使用 ProxyProvider 来达到这个目的。

ProxyProvider 是一个基于其他提供者构建价值的提供者。

你说你有一个 MultiProvider,所以我猜你在这个 MultiProvider 中有 SharedPreferencesData 个提供者,然后是 DatabaseService 个提供者。您需要做的是将 ProxyProvider 用于 DatabaseService 而不是常规提供程序,并将其基于 SharedPreferencesData 提供程序。

这是一个例子:

MultiProvider(
  providers: [
    ChangeNotifierProvider<SharedPreferencesData>(
      create: (context) => SharedPreferencesData(),
    ),
    ProxyProvider<SharedPreferencesData, DatabaseService>(
      create: (context) => DatabaseService(),
      update: (context, sharedPreferencesData, databaseService) {
        databaseService.sharedPreferencesData = sharedPreferencesData;
        return databaseService;
      },
      dispose: (context, databaseService) => databaseService.dispose(),
    ),
  ],
  child: ...

上面的代码片段是这样的:

  1. ProxyProvider 每次 SharedPreferencesData 变化时调用 update
  2. DatabaseServiceupdate.
  3. 中设置其 sharedPreferencesData 变量

现在您可以访问 DatabaseService 实例中的 sharedPreferencesData,您可以轻松地做您想做的事了。