Передайте объект additonalUserInfo в модель User из класса FirebaseAuthService во Flutter - PullRequest
0 голосов
/ 09 апреля 2020

Я занимаюсь разработкой флаттера, следуя этой архитектуре, которую можно визуализировать здесь . Существует требование, что мне нужно использовать другой входящий поток, когда пользователь регистрируется впервые, помимо обычного потока.

Итак, немного покопавшись, я обнаружил, что Firebase предоставляет переменная bool isNewUser в объекте additionalUserInfo класса AuthResult. Поэтому, естественно, моей первой мыслью было передать это bool в модель User, чтобы я мог проверить, зарегистрировался ли пользователь впервые и пройти соответствующий маршрут в классе AuthWidget, как этот.

class AuthWidget extends StatelessWidget {
  const AuthWidget({Key key, @required this.userSnapshot}) : super(key: key);
  final AsyncSnapshot<User> userSnapshot;

  @override
  Widget build(BuildContext context) {
    if (userSnapshot.connectionState == ConnectionState.active) {
      if (userSnapshot.hasData) {
        return userSnapshot.data.isNew ? OnBoardingPage() : RootWidget();  
      } else {
        return SignInPageBuilder();
      }
    }
    return Scaffold(
        body: Center(
      child: CircularProgressIndicator(),
    ));
  }
}

Поэтому, передавая логическую переменную в пользовательскую модель из моего класса FirebaseAuthService, я столкнулся с некоторыми проблемами. Это то, что я думал делать в классе FirebaseAuthService. Я оставил комментарии внутри кода для лучшего понимания.

class FirebaseAuthService {
  final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;

  User _userFromFirebase(FirebaseUser user, AdditionalUserInfo additionalUserInfo) {
    if(user == null){
      return null;
    }
    return User(
      uid: user.uid,
      email: user.email,
      photoUrl: user.photoUrl,
      displayName: user.displayName,
      isNew: additionalUserInfo.isNewUser // Passing this new variable from the AdditionalUserInfo var we passed as an argument
    );
  }

  Stream<User> get onAuthStateChanged {
    // This is where the first trouble is. The linter shows me the error : 
    // The argument type 'User Function(FirebaseUser, AdditionalUserInfo)' can't be assigned to the parameter type 'User Function(FirebaseUser)'.
    // So I guess no other arguments can be passed to the _userFromFirebase function
    return _firebaseAuth.onAuthStateChanged.map(_userFromFirebase);
  }

  Future<User> signInUsingGoogle() async {
    final GoogleSignIn googleSignIn = GoogleSignIn();
    final GoogleSignInAccount googleSignInAccount = await googleSignIn.signIn();
    final GoogleSignInAuthentication googleSignInAuthentication = await googleSignInAccount.authentication;
    final AuthCredential credential = GoogleAuthProvider.getCredential(
      idToken: googleSignInAuthentication.idToken, 
      accessToken: googleSignInAuthentication.accessToken
    );
    final AuthResult authResult = await _firebaseAuth.signInWithCredential(credential);
    // passing the additionalUserInfo variable
    return _userFromFirebase(authResult.user, authResult.additionalUserInfo);
  }

  Future<User> signInUsingFacebook() async {
    final FacebookLogin facebookLogin = FacebookLogin();
    final FacebookLoginResult facebookLoginResult = await facebookLogin.logIn(['email']);
    switch(facebookLoginResult.status) {
      case FacebookLoginStatus.cancelledByUser:
        print("Cancelled by user");
        break;
      case FacebookLoginStatus.error:
        print("error sigining using facebook");
        break;
      case FacebookLoginStatus.loggedIn:
        print("Logged In with facebook");
        break;
    }
    final accessToken = facebookLoginResult.accessToken.token;
    if(facebookLoginResult.status == FacebookLoginStatus.loggedIn) {
      final facebookAuthcred = FacebookAuthProvider.getCredential(accessToken: accessToken);
      final AuthResult authResult = await _firebaseAuth.signInWithCredential(facebookAuthcred);
      // Same as Google login flow
      return _userFromFirebase(authResult.user, authResult.additionalUserInfo);
    }
    return null;
  }

  Future<User> currentUser() async {
    final FirebaseUser user = await _firebaseAuth.currentUser();
    // This is the second confusion.
    // Since we don't have an AuthResult object, how do I pass that variable.
    // I could set the default value for the variable to null/false but I don't think that will be a scalable solution
    return _userFromFirebase(user);
  }

  Future<void> signOut() async {
    return _firebaseAuth.signOut();
  }

}

Пожалуйста, предложите, если есть лучший способ реализовать это. Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...