authStateChanges 仅在调试模式下工作

时间:2021-02-18 00:36:58

标签: flutter firebase-authentication release

我有一个 flutter 应用程序,一切都很好,直到我想发布它。 我正在使用 firebase 进行身份验证。

我正在使用:
firebase_core: ^0.7.0
firebase_auth:^0.20.0

在调试模式或发布中,我的 firebase 身份验证登录工作正常。我的问题是在那之后。 我有一个针对 firebaseAuth.authStateChanges 的去中心化“监听器”。这是我控制我的应用程序身份验证的地方。这是我的身份验证存储库中的 buildSelf$ 函数(我在其中构建身份验证状态侦听器):

    ReplayConnectableStream<AuthState> buildSelf$() {
        return Rx.concat([
          Stream.value(AuthInit()),
          firebaseAuth.authStateChanges().switchMap((firebaseUser) {
            print('[AuthRepository][buildSelf][authStateChanges] firebaseUser');
            print(firebaseUser);
            if (firebaseUser == null) {
              return Stream.value(Unauthenticated());
            }
            /* continue function */
            return Authenticated(firebaseUser: firebaseUser);
          })
        ]).publishReplay();
    }

buildSelf$ 是我的 AuthRepository 的一种方法。我将其初始化为:

  AuthRepository._() {
    Firebase.initializeApp().then((app) {
      _firebaseAuth = FirebaseAuth.instance;
      state$ = buildSelf$();
      state$.connect();
    });
    setPackageInfo();
  }

  static final AuthRepository instance = AuthRepository._();

所有这些代码都在我的 AuthRepository 中。 问题是: 当我在调试模式下运行我的应用程序时。一切正常。我可以登录我的应用程序(我的导航观察者使用身份验证存储库 state$),然后我被重定向到主页。 [这里是 debug mode. success authStateChanges emit 中终端的打印屏幕 但是当我运行即时发布模式时,我的登录响应显示在我的终端“成功”中,但我的监听器没有显示状态更改。这是 release mode. authStateChanges emit only 1 time(when opening)

中终端的打印屏幕

我真的不知道发生了什么。我什至尝试在我的 app.dart 中直接调用这个 authStateChanges 但仍然是相同的方式(在发布中,只检查一次 auth 状态)。

解决方案:

  • 头痛了 3 天后,我终于发现了我的问题: 我的应用程序没有在 root (main) 上初始化 firebase 应用程序。所以每次我需要使用一些 firebase 包时我都必须初始化它。 我相信每次初始化一个应用程序时,其他应用程序都会失败。

我将我的 firebase.initializeApp() 移动到我的主函数并删除所有其他 firebase 初始化。然后,一切正常。 这是我的主要内容:

void main() async {
    /* ... main code ... */
    WidgetsFlutterBinding.ensureInitialized();
    await Firebase.initializeApp();
    runApp(App());
}

1 个答案:

答案 0 :(得分:-1)

我确实在 iPhone 的发布模式下使用所提供的方法实施了一个项目,但无法重现该问题,我为重现该项目所做的实施是:

class _TestFirebaseState extends State<TestFirebase> {
  bool userLogado = false;

  _loginLogout() {
    if (FirebaseAuth.instance.currentUser == null) {
      FirebaseAuth.instance.signInWithEmailAndPassword(
          email: 'teste1@teste.com', password: '123456');
    } else {
      FirebaseAuth.instance.signOut();
    }
  }

  @override
  void initState() {
    super.initState();

    final stream = Rx.concat(
      [
        Stream.value('começou'),
        FirebaseAuth.instance.authStateChanges().switchMap<String>(
          (user) {
            debugPrint('user: ' + user.toString());
            if (user == null) {
              return Stream.value('unauth');
            } else {
              return Stream.value('auth');
            }
          },
        ),
      ],
    ).publishReplay();

    stream.listen((value) {
      debugPrint('value: ' + value);
      this.setState(() {
        this.userLogado = value == 'auth';
      });
    });

    stream.connect();
    
  }

  @override
  Widget build(BuildContext context) {
    String text = "sair";
    if (!userLogado) {
      text = "entrar";
    }

    return Scaffold(
      body: Container(
        width: double.infinity,
        height: double.infinity,
        child: Center(
          child: RaisedButton(
            onPressed: _loginLogout,
            child: Text(text),
          ),
        ),
      ),
    );
  }
}

唯一的细节是加载应用程序中所有内容的主要组件有一个等待 Firebase 初始化的未来构建器:

Widget build(BuildContext context) {
    return MaterialApp(
      home: FutureBuilder(
        // Initialize FlutterFire:
        future: Firebase.initializeApp(),
        builder: (context, snapshot) {
          // Check for errors
          if (snapshot.hasError) {
            return Scaffold(
              body: Center(
                child: Text(
                  'ocorreu um problema inicializando o aplicativo...',
                ),
              ),
            );
          }

          // Once complete, show your application
          if (snapshot.connectionState == ConnectionState.done) {
            // return LoginPage();
            // return VerifySignIn(homePage: Home());
            return TestFirebase();
          }

          // Otherwise, show something whilst waiting for initialization to complete
          return Scaffold(
            body: Center(
              child: CircularProgressIndicator(),
            ),
          );
        },
      ),
      debugShowCheckedModeBanner: false,
    );
}

另一个细节是,firebase 配置是按照所用平台的 flutter 教程实现的。

因此,为了评估应用配置是否正常,我会在同一个项目中实现该按钮应用,以便您可以正确评估它。