无状态小组件未使用StreamProvider更新

时间:2020-05-15 13:25:42

标签: firebase flutter firebase-authentication flutter-provider

我正在尝试使用StreamProvider来使我的应用在用户登录时显示Features小部件。这是我的代码:

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

import 'auth/auth.dart';
import 'features/features.dart';

void main() => runApp(
      StreamProvider<FirebaseUser>(
          create: (context) => FirebaseAuth.instance.onAuthStateChanged,
          child: MaterialApp(home: MyApp()),
          updateShouldNotify: (_, __) => true),
    );

class MyApp extends StatelessWidget {
  static reload(BuildContext context) {
    Navigator.pushAndRemoveUntil(
      context,
      MaterialPageRoute(builder: (context) => MyApp()),
      (Route<dynamic> route) => false,
    );
  }

  @override
  Widget build(BuildContext context) {
    var _user = Provider.of<FirebaseUser>(context);
    print('USER ISSUED: ' + _user.toString());
    if (_user == null) return SignInPage();
    if (_user != null) return Features();
  }
}

我必须创建reload()方法,该方法由嵌套在SignInPage下面的各种身份验证小部件(google,facebook,密码)调用,以更新MyApp的显示。我曾期望Provider.of<FirebaseUser>将自动重建我的应用程序,而无需调用reload()Provider确实有效。每当FirebaseAuth更新用户时,它都会输出USER ISSUED: some_user...。为什么在用户成功登录后,SignInPage不会返回我的user == null页面,或者在用户成功登录后返回Features页面,为什么它不执行后两行代码?

我是FlutterFire的新手,但来自AngularFire,我希望它能顺利运行。

1 个答案:

答案 0 :(得分:0)

我认为您应该使用:

// (firebase_auth 0.9.0)

StreamProvider.value(
    value: FirebaseAuth.instance.onAuthStateChanged,
    child: MaterialApp(home: MyApp()),
  ),

因为根据docs StreamProvider.valuevalue并将其公开给所有StreamProvider后代。

但是,这里最好使用StreamBuilder,因为您可能想检查是否已建立连接,否则,每次打开应用程序时,它都会显示登录屏幕的一瞥,然后自动进入主屏幕。在中等网络条件下,如果缓存了用户身份验证。

// (fireabse_auth 0.18.4)

StreamBuilder(
    stream: FirebaseAuth.instance.authStateChanges(),
    builder: (_, snapshot) {
      if (snapshot.connectionState == ConnectionState.waiting) {
        return Loading();
      }
      if (snapshot.data is User && snapshot.data != null) {
        return Home();
      }
      return Authenticate();
    })

我希望Provider.of会自动重建我的应用程序

StreamProvider负责侦听流,将其公开给后代并更新使用者的状态,而不是Provider.of<T>(context)Provider.of<T>(context)只是尝试从最近的T父提供者那里访问T类型的数据。