Redirection d'un nouvelle utilisateur avec provider

Bonjour a tous,
Je viens vers vous car je ne trouve pas la solution a mon problème.
Je souhaite rediriger mon utilisateurs vers une page « signup » si l’utilisateurs est nouveau dans « firebase-firestore », après qu’il ce soit loguer avec google ou un autres.

J’utilise provider, mon appli fonctionne très bien pour rediriger vers ma page « signin » ou ma page « home » mais je ne trouve pas pour le « signup ».

En gros, si l’utilisateur clique sur la connexion via google, et qu’il est nouveau il va vers « signup »

j’utilise le stream provider ce qui complique les choses.

Voici mon code:

class FirebaseAuthService implements AuthService {
  final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;


  MyAppUser _userFromFirebase(User user) {
    if (user == null) {
      return null;
    }
    return MyAppUser(
      uid: user.uid,
      email: user.email,
      displayName: user.displayName,
      photoUrl: user.photoURL,
    );
  }

  @override
  Stream<MyAppUser> get onAuthStateChanged {
    return _firebaseAuth.authStateChanges().map(_userFromFirebase);
  }

  @override
  Future<MyAppUser> signInAnonymously() async {
    final UserCredential userCredential =
        await _firebaseAuth.signInAnonymously();
    return _userFromFirebase(userCredential.user);
  }

  @override
  Future<MyAppUser> signInWithEmailAndPassword(
      String email, String password) async {
    final UserCredential userCredential =
        await _firebaseAuth.signInWithEmailAndPassword(
      email: email,
      password: password,
    );
    return _userFromFirebase(userCredential.user);
  }

  @override
  Future<MyAppUser> createUserWithEmailAndPassword(
      String email, String password) async {
    final UserCredential userCredential = await _firebaseAuth
        .createUserWithEmailAndPassword(email: email, password: password);
    return _userFromFirebase(userCredential.user);
  }

  @override
  Future<void> sendPasswordResetEmail(String email) async {
    await _firebaseAuth.sendPasswordResetEmail(email: email);
  }

  @override
  Future<MyAppUser> signInWithEmailAndLink({String email, String link}) async {
    final UserCredential userCredential =
        await _firebaseAuth.signInWithEmailLink(email: email, emailLink: link);
    return _userFromFirebase(userCredential.user);
  }

  @override
  bool isSignInWithEmailLink(String link) {
    return _firebaseAuth.isSignInWithEmailLink(link);
  }

  @override
  Future<void> sendSignInWithEmailLink({
    @required String email,
    @required String url,
    @required bool handleCodeInApp,
    @required String iOSBundleId,
    @required String androidPackageName,
    @required bool androidInstallApp,
    @required String androidMinimumVersion,
  }) async {
    return await _firebaseAuth.sendSignInLinkToEmail(
      email: email,
      actionCodeSettings: ActionCodeSettings(
        url: url,
        handleCodeInApp: handleCodeInApp,
        iOSBundleId: iOSBundleId,
        androidPackageName: androidPackageName,
        androidInstallApp: androidInstallApp,
        androidMinimumVersion: androidMinimumVersion,
      ),
    );
  }

  @override
  Future<MyAppUser> signInWithGoogle() async {
    final GoogleSignIn googleSignIn = GoogleSignIn();
    final GoogleSignInAccount googleUser = await googleSignIn.signIn();

    if (googleUser != null) {
      final GoogleSignInAuthentication googleAuth =
          await googleUser.authentication;
      if (googleAuth.accessToken != null && googleAuth.idToken != null) {
        final UserCredential userCredential = await _firebaseAuth
            .signInWithCredential(GoogleAuthProvider.credential(
          idToken: googleAuth.idToken,
          accessToken: googleAuth.accessToken,));

        //test redirection signup
       if (userCredential.additionalUserInfo.isNewUser) {
          print ('testsignup');
          //SignUp();
        } else {
          print ('notestsignup');
        }


        return _userFromFirebase(userCredential.user);
      } else {
        throw PlatformException(
            code: 'ERROR_MISSING_GOOGLE_AUTH_TOKEN',
            message: 'Missing Google Auth Token');
      }
    } else {
      throw PlatformException(
          code: 'ERROR_ABORTED_BY_USER', message: 'Sign in aborted by user');
    }
  }

Mon builder widget:

class AuthWidgetBuilder extends StatelessWidget {
  const AuthWidgetBuilder({Key key, @required this.builder}) : super(key: key);
  final Widget Function(BuildContext, AsyncSnapshot<MyAppUser>) builder;

  @override
  Widget build(BuildContext context) {
    final authService = Provider.of<AuthService>(context, listen: false);
    return StreamBuilder<MyAppUser>(
      stream: authService.onAuthStateChanged,
      builder: (BuildContext context, AsyncSnapshot<MyAppUser> snapshot) {
        final MyAppUser user = snapshot.data;
        if (user != null) {
          return MultiProvider(
            providers: [
              Provider<MyAppUser>.value(value: user),
              // NOTE: Any other user-bound providers here can be added here
            ],
            child: builder(context, snapshot),
          );
        }
        return builder(context, snapshot);
      },
    );
  }
}

et mon AuthWidget: (pour le redirection, qui vérifie le snapshot)

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

  @override
  Widget build(BuildContext context) {
    // cherche soluce pour rediriger vers signup si new user
      if (userSnapshot.connectionState == ConnectionState.active) {
        return userSnapshot.hasData ? HomePage() : SignInPageBuilder();
      }
      return Scaffold(
        body: Center(
          child: CircularProgressIndicator(),
        ),
      );
    }
  }

J’ai cherché de tout les coté sans résultat… comme vous pouvez le voir je test « isNewUser », mais comme je fait du « stream sur onAuthStateChanged » l’état change avant mon if isNewUser, donc la redirection vers mon home ce fait avant, donc la redirection vers mon SignUp ne pourra pas fonctionner…

J’éspère avoir été claire, et si besoins de plus d’infos, je repondrais volontier.

Merci pour votre aide.

Il serait mieux que tu utilises un future(tu pourras faire attendre le code) plus tôt que le stream et en y ajoutant le provider cela fera l’affaire. Aussi c’est bizarre mais j’ai jamais vu une classe avec autant de @override. Tu pourrais créer plusieurs fonctions a lanc6lors de l’initialisation de la class.

Bonjour, merci pour ta réponse.
j’ai mis des overrides car j’ai des superclass sont utilisé ailleurs et pour la lisibilité.

Je ne comprend pas ta remarque sur le future? changer

stream: authService.onAuthStateChanged,

en future?

Je stream « AuthService » ca m’évite d’avoir a faire un « stream » pour chaque methode d’identification.

Merci pour ton avis en tout cas je prend :slight_smile:

Bonjour,

Si tu as d’autres données par la suite à stocker, il serait plus simple pour toi de stocker ces données dans une BDD comme Cloud Firestore.
À ce moment là, tu peux insérer la partie BDD après l’authentification et vérifier si ton utilisateur est nouveau.
FirebaseAuth est surtout une couche de sécurité, pour des fonctionnalités supplémentaires une base de donnée fera l’affaire.

Oui en effet c’est ce qui est prévu. Je souhaiterai après l’authentification FirebaseAuth, redirigé vers une page Signup qui la servira a rajouté les données dans Cloud Firestore.

il faut juste que j’arrive a implémenté le « additionalUserInfo.isNewUser » pour redirigé vers mon Signup et la creer les donées avec Cloud Firestore.

Je sais pas si c’est claire et si c’est la meilleur solution…

Merci pour vos avis en tout cas :slight_smile:

PS: je n’ai pas afficher tout mon code, il y en a beaucoup^^

Ce que tu peux faire c’est récupérer l’email après authentification via Google avec la commande suivante à adapter :

_user = userCredential.user; _user.email;
Donc à la suite de ton code avant la redirection, tu as l’email de l’utilisateur et tu vas pouvoir vérifier si cette email est déjà dans ta base de donnée.

Si c’est le cas, cela veut dire que ce n’est pas un nouvel utilisateur et donc redirection sur la bonne page.