如何使用scopeModel在Flutter中收听Firestore文档中的实时更改

时间:2019-05-21 11:31:12

标签: flutter

我的模型设置如下:

// scope.model.dart
mixin AuthModel on CoreModel {
  bool get isLoading => _isLoading;
  get notification => _notification;
  Observable<Map<String, dynamic>> profileUser;

  // constructor
  Future<void> authService() async {
    user = Observable(_auth.onAuthStateChanged);

    profileUser = user.switchMap((FirebaseUser u) {
      if (u != null) {
        authenticated.add(true);
        _isLoading = false;
        notifyListeners();
        return _db
            .collection('users')
            .document(u.uid)
            .snapshots()
            .map((snap) => snap.data);
      } else {
        authenticated.add(false);
        return Observable.just({});
      }
    });
  }

// get profile here
}

要获取用户个人资料,我正在做这种事情:

get profile {
   profileUser.listen((user) => _profile = user);
    if (_profile == null) {
      _isLoading = true;
      notifyListeners();
    } else {
      return _profile;
    }
  }

_profile被初始化为对象!

然后在我的屏幕或带有scopeModel的页面中,我简单地做

_model.profile['username'];

这行得通,问题是当更改Firestore文档信息时,除非我更改路线或刷新应用程序,否则它在屏幕视图上不会更改。

我是新来的,在扑朔迷离中挣扎,这样做的正确方法是什么?

1 个答案:

答案 0 :(得分:0)

如果您要使用FirebaseUser并希望跟踪状态 或已在整个应用程序中登录的用户,我建议您在应用程序的最高级别上使用提供程序。

对我来说,最简单的方法是使用Provider Package,根据一些教程/视频,它基本上是ScopedModel v2

示例

void main() {

   runApp(MyApp());
   }

class MyApp extends StatelessWidget {
  MyApp();

  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        StreamProvider<FirebaseUser>.value(
          stream: FirebaseAuth.instance.onAuthStateChanged, // Provider here
        ),
      ],
      child: MaterialApp(
        title: 'My App',
        debugShowCheckedModeBanner: false,
        theme: ThemeData(
          primaryColor: Colors.green,
          primarySwatch: Colors.green,
          accentColor: Colors.yellow,
        ),
        home: MainPage(),
      ),
    );
  }
}

class MainPage extends StatefulWidget {
  MainPage({Key key, this.storage}) : super(key: key);
  final FirebaseStorage storage;
  @override
  _MainPageState createState() => _MainPageState();
}

class _MainPageState extends State<MainPage>
    with SingleTickerProviderStateMixin {
  @override
  Widget build(BuildContext context) {
    final user = Provider.of<FirebaseUser>(context); // gets the firebase user
    bool loggedIn = user != null;

    return loggedIn ? HomePage() : LoginPage(); // Will check if the user is logged in. And will change anywhere in the app if the user logs in
  }
}

其他参考资料(对我有帮助)

Fireship 185 Provider

Great Youtube video explaining the code