检查用户是否在FIrestore上

我具有使用SignInWithGogle来登录/注册用户的功能

 void _signInWithGoogle() async {
    final GoogleSignInaccount googleUser = await _googleSignIn.signIn();
    final GoogleSignInAuthentication googleAuth =
        await googleUser.authentication;
    final AuthCredential credential = GoogleAuthProvider.getcredential(
      accessToken: googleAuth.accessToken,idToken: googleAuth.idToken,);
    final FirebaseUser user = (await _auth.signInWithCredential(credential)).user;
    assert(user.email != null);
    assert(user.displayName != null);
    assert(!user.isAnonymous);
    assert(await user.getIdToken() != null);

    final FirebaseUser currentUser = await _auth.currentUser();
    assert(user.uid == currentUser.uid);
    print('user email here $user.email');
    setState(() {
      if (user != null) {
        _success = true;
        _userID = user.uid;
        final userToSubmit = User(
            email: user.email,id: user.uid,name: user.displayName,owner: false,favorites: null);
        print('USER ID USER ID USER ID ${user.uid}');
        DocumentReference dbRef =
            Firestore.instance.collection('users').document(user.uid);
        dbRef.get().then((value) {
          print('VALUE EXISTS? ${value.exists} y VALUE $value');
          value.exists ?
            _goToHomeScreen(user)
          :
          dbRef
              .collection('prf')
              .document('profile')
              .setData(userToSubmit.toJson())
              .then(_goToHomeScreen(user));
        });
      } else {
        _success = false;
      }
    });
  }

问题是,当用户注销并再次登录时,它会设置新数据,并且用户丢失了自己喜欢的所有内容,依此类推……我认为检查文档是否存在应该可以解决问题,尽管文档是否存在返回false。 这是我正在谈论的代码片段

DocumentReference dbRef =
                Firestore.instance.collection('users').document(user.uid);
            dbRef.get().then((value) {
              print('VALUE EXISTS? ${value.exists} y VALUE $value');
              value.exists ?
                _goToHomeScreen(user)
              :
              dbRef
                  .collection('prf')
                  .document('profile')
                  .setData(userToSubmit.toJson())
                  .then(_goToHomeScreen(user));
            });
          }

为什么即使user.uid和文档存在也返回false?我在做什么错了?

oxiang741 回答:检查用户是否在FIrestore上

我实现的最终解决方案是:

 FirebaseUser firebaseUser;
    try {
      firebaseUser = (await FirebaseAuth.instance.signInWithCredential(credential)).user;
    } catch(e) {
      print(e.toString());
    } finally {
      final userToSubmit = User(
          email: firebaseUser.email,id: firebaseUser.uid,name: firebaseUser.displayName,owner: false,restauranteAdded: false);
      DocumentReference dbRef =
      Firestore.instance.collection('users').document(firebaseUser.uid).collection('nameOfTheCollection').document('documentName');

      dbRef.get().then((data) {
        data.exists ? _goToHomeScreen(user) :  
          _createUser();
      });

通过这种方式,我检查用户文档是否存在于Firestore数据库中,如果不存在,它将创建该文档。

,

发生了很多事情。通常,您不会使用state方法更新任何setState()对象。 setState用于告诉窗口小部件某些state已更改-并且与更改一起被称为 ,但是在这里,您只是在检查文档是否存在,没有任何变化,这是不需要的。

而且看来您根本没有真正返回user对象,因此在我阅读本文时,此代码将始终返回false

  1. 您应该在此处完全删除setState(执行此操作不需要)
  2. 运行登录方法,该方法返回您要执行操作的用户对象。
  3. 一旦您知道已登录的用户(即带有已登录用户的uid),便可以访问数据库

这里是尝试的选项:

//Create a User class so that you don't have to call FireBase in your methods.
class User {
  User({
    @required this.uid,this.email,this.displayName,});
  final String uid;
  final String email;//these are whatever you want
  final String displayName;
}

//put sign in methods into an abstract class. Don't have to,but keeps code flexible if you don't stay with firebase
abstract class AuthBase {
 //add in other signin methods as needed
  Future<User> signInWithGoogle();

}

//Implement AuthBase in class Auth
class Auth implements AuthBase {
  final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;

//Get a User from Firebase User
  User _userFromFirebase(FirebaseUser user) {
    if (user == null) {
      return null;
    }
    return User(
      uid: user.uid,displayName: user.displayName,email: user.email,);
  }

//your signinWithGoogle method
Future<User> signInWithGoogle() async {
  //where User is the class you've created
  GoogleSignIn googleSignIn = GoogleSignIn();
  GoogleSignInAccount googleUser = await googleSignIn.signIn();

  if (googleUser != null) {
    GoogleSignInAuthentication googleAuth = await googleUser.authentication;
    if (googleAuth.idToken != null && googleAuth.accessToken != null) {
      final authResult = await _firebaseAuth.signInWithCredential( //await your instance of FirebaseAuth
        GoogleAuthProvider.getCredential(
          idToken: googleAuth.idToken,accessToken: googleAuth.accessToken,),);

      return _userFromFirebase(authResult.user); //your signed in firebase user that you can do stuff with uid,email,displayname,etc.
    } else {
      throw PlatformException(
        code: 'ERROR_MISSING_GOOGLE_AUTH_TOKEN',message: '',);
    }
  } else {
    throw PlatformException(
      code: 'ERROR_ABORTED_BY_USER',);
  }
}

本文链接:https://www.f2er.com/3150324.html

大家都在问