简体   繁体   English

Flutter Firebase auth bloc return Firebase auth user and firestore datas in same stream

[英]Flutter Firebase auth bloc return Firebase auth user and firestore datas in same stream

I'm trying to handle firebase authentication and acces user datas from cloud firestore with BloC .我正在尝试处理 firebase 身份验证并使用BloC从 cloud firestore 访问用户数据。 I use the flutter firebase login tutorial from the bloc library.我使用 bloc 库中的flutter firebase 登录教程 In this tutorial we can manipulate user authentication with firebase and get the auth User datas from the authStateChanges() and create a stream on changes.在本教程中,我们可以使用 firebase 操作用户身份验证,并从 authStateChanges() 获取 auth 用户数据,并在更改时创建 stream。 I would like to read datas from cloud firestore and add those datas to the same stream.我想从云 firestore 读取数据并将这些数据添加到相同的 stream。

The original Stream from authentication_resposiroty.dart :来自authentication_resposiroty.dart的原始 Stream :

     /// Stream of [User] which will emit the current user when
      /// the authentication state changes.
      ///
      /// Emits [User.empty] if the user is not authenticated.
      Stream<User> get user {
        return _firebaseAuth.authStateChanges().map((firebaseUser) {
          print('User: $firebaseUser');
    
          final user = firebaseUser == null ? User.empty : firebaseUser.toUser;
          _cache.write(key: userCacheKey, value: user);
          return user;
        });
      }

extension on firebase_auth.User {
  User get toUser {
    return User(
      id: uid,
      email: email,
      photo: photoURL,
      emailVerified: emailVerified,
    );
  }
}

I try somethiing like that:我尝试这样的事情:

/// Stream of [User] which will emit the current user when
  /// the authentication state changes.
  ///
  /// Emits [User.empty] if the user is not authenticated.
  Stream<User> get user {
    return _firebaseAuth.authStateChanges().asyncExpand<User>((firebaseUser) {
      print('User: $firebaseUser');

      if (firebaseUser == null) {
        final user = User.empty;
        _cache.write(key: userCacheKey, value: user);
        print('User: firebaseUser == null :  $user');
        return Stream.value(user);
      } else {
        return _firebaseFirestore
            .collection('Users')
            .doc(firebaseUser.uid)
            .snapshots()
            .map((snapshot) {
          final user = User(
            id: firebaseUser.uid,
            email: firebaseUser.email,
            emailVerified: firebaseUser.emailVerified,
            datas: snapshot.data(),
          );
          _cache.write(key: userCacheKey, value: user);
          print('User: firebaseUser not null $user');
          return user;
        });
      }
    });
  }

This work, i can read my user datas from firestore and if I modify my datas drome firestore the update well, but I have some issues, when i try to login, the stream takes time and my redirection doesn't work because I check if the user.emailVerified is True, the stream is updated after my verification, I have to press my loggin button a second time... and then when I want to logout, I have then next error that I don't have before with the original code:这项工作,我可以从 firestore 读取我的用户数据,如果我修改我的数据 drome firestore 更新很好,但我有一些问题,当我尝试登录时,stream 需要时间并且我的重定向不起作用,因为我检查是否user.emailVerified 是 True,stream 在我验证后更新,我必须再次按下我的登录按钮......然后当我想注销时,我遇到了下一个错误,这是我以前没有的原始代码:

I/flutter (22885): AppLogoutRequested()
D/FirebaseAuth(22885): Notifying id token listeners about a sign-out event.
D/FirebaseAuth(22885): Notifying auth state listeners about a sign-out event.
W/Firestore(22885): (24.2.1) [Firestore]: Listen for Query(target=Query(Users/YyvBbHtujyNXZser92XfEfDSRqY2 order by __name__);limitType=LIMIT_TO_FIRST) failed: Status{code=PERMISSION_DENIED, description=Missing or insufficient permissions., cause=null}
E/flutter (22885): [ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: [cloud_firestore/permission-denied] The caller does not have permission to execute the specified operation.
E/flutter (22885):

It looks like I'm not logged but I'm.看起来我没有登录,但我登录了。

I start with flutter and bloc so sorry if it's not clear...我从 flutter 开始,如果不清楚,我很抱歉......

Thank you in advance for your answers.预先感谢您的回答。

If I understand correctly, the security rules of your Users collection require that a user is signed in to read the/their data.如果我理解正确,您的Users集合的安全规则要求用户登录才能阅读/他们的数据。

It looks like your code successfully subscribes to the data in Firestore when the user signs in, which means you have a persistent listener checking for updates to that data.看起来您的代码在用户登录时成功订阅了 Firestore 中的数据,这意味着您有一个持久的侦听器来检查该数据的更新。

But when the user signs out, the listener no longer meets the requirement of your security rules, so it gets canceled automatically by Firestore at that point.但是当用户注销时,侦听器不再满足您的安全规则的要求,因此此时它会被 Firestore 自动取消。 This is when you get the error message.这是您收到错误消息的时候。

To prevent getting the error message, you can detach the listener before logging the user out.为防止收到错误消息,您可以在注销用户之前分离侦听器。 The.net result will be the same, but by detaching it on time you will not get the error message from the server. .net 结果将是相同的,但通过按时分离它,您将不会从服务器收到错误消息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM