signInWithGoogle method

Future<UserCredential> signInWithGoogle()

Signs in the user using Google authentication and returns the user credential.

Implementation

Future<UserCredential> signInWithGoogle() async {
  try {
    await _ensureGoogleSignInInitialized();
    const scopeHint = ['email', 'profile'];
    // Sign out current user if not anonymous
    if (_auth.currentUser != null && _auth.currentUser!.isAnonymous != true) {
      await _auth.signOut();
    }

    if (_auth.currentUser != null && _auth.currentUser!.isAnonymous == true) {
      // Trigger the authentication flow
      final googleUser = await _googleSignIn.authenticate(
        scopeHint: scopeHint,
      );
      // Obtain the auth details from the request
      final googleAuth = googleUser.authentication;
      final authz = await googleUser.authorizationClient
          .authorizationForScopes(scopeHint);
      final accessToken = authz?.accessToken ??
          (await googleUser.authorizationClient.authorizeScopes(scopeHint))
              .accessToken;
      if (googleAuth.idToken is String || accessToken.isNotEmpty) {
        // Create a new credential
        final googleCredential = GoogleAuthProvider.credential(
          accessToken: accessToken,
          idToken: googleAuth.idToken,
        );

        final credential =
            await _auth.currentUser!.linkWithCredential(googleCredential);

        await _auth.currentUser!.reload();
        if (_auth.currentUser!.email is String &&
            _auth.currentUser!.email!.isNotEmpty) {
          await resendEmailVerification(_auth.currentUser!.email!);
        }
        return credential;
      } else {
        throw AuthDataServiceException(
          message: 'Google Sign In Failed',
        );
      }
    }

    // Trigger the authentication flow
    final googleUser = await _googleSignIn.authenticate(
      scopeHint: scopeHint,
    );
    // Obtain the auth details from the request
    final googleAuth = googleUser.authentication;
    final authz =
        await googleUser.authorizationClient.authorizationForScopes(
      scopeHint,
    );
    final accessToken = authz?.accessToken ??
        (await googleUser.authorizationClient.authorizeScopes(scopeHint))
            .accessToken;
    if (googleAuth.idToken is String || accessToken.isNotEmpty) {
      // Create a new credential
      final credential = GoogleAuthProvider.credential(
        accessToken: accessToken,
        idToken: googleAuth.idToken,
      );
      return await _auth.signInWithCredential(credential);
    } else {
      throw AuthDataServiceException(
        message: 'Google Sign In Failed',
      );
    }
  } catch (err) {
    if (err is FirebaseAuthException) {
      throw AuthDataServiceException.fromRdevException(err.toRdevException());
    }
    if (err is AuthDataServiceException) {
      rethrow;
    }
    throw AuthDataServiceException(
      message: err.toString(),
    );
  }
}