import 'package:firebase_auth/firebase_auth.dart'; import 'package:google_sign_in/google_sign_in.dart'; final _auth = FirebaseAuth.instance; Future signInWithGoogle() async { try { // Trigger the authentication flow final GoogleSignInAccount googleUser = await GoogleSignIn.instance.authenticate(); // Obtain the auth details from the request final GoogleSignInAuthentication googleAuth = googleUser.authentication; // Create a new credential final credential = GoogleAuthProvider.credential(idToken: googleAuth.idToken); // Once signed in, return the UserCredential return await FirebaseAuth.instance.signInWithCredential(credential); } catch (e) { // Handle and map Google sign-in specific errors final msg = mapAuthErrorGoogle(e.toString()); throw Exception(msg); } } // flutter: Google sign-in failed: PlatformException(google_sign_in, Your app is missing support for the following URL schemes: com.googleusercontent.apps.441447288850-m7pld8j4gv8k1guc5l0jpk1auqi93mna, NSInvalidArgumentException, null) Future signUpEmail({required String email, required String password}) async { try { return await _auth.createUserWithEmailAndPassword(email: email.trim(), password: password); } on FirebaseAuthException catch (e) { throw _mapAuthError(e); } } Future signInEmail({required String email, required String password}) async { try { return await _auth.signInWithEmailAndPassword(email: email.trim(), password: password); } on FirebaseAuthException catch (e) { throw _mapAuthError(e); } } Future signOut() => _auth.signOut(); Stream get authState => _auth.authStateChanges(); String _mapAuthError(FirebaseAuthException e) { switch (e.code) { case 'invalid-email': return 'The email address is badly formatted.'; case 'user-disabled': return 'This account has been disabled.'; case 'user-not-found': return 'No account found with this email.'; case 'wrong-password': return 'Incorrect password.'; case 'email-already-in-use': return 'An account already exists with this email.'; case 'weak-password': return 'Please choose a stronger password.'; case 'operation-not-allowed': return 'Email/Password is disabled in Firebase Console.'; default: return 'Authentication failed. (${e.code})'; } } String mapAuthErrorGoogle(Object e) { // Some errors come wrapped in PlatformException or GoogleSignInException. final msg = e.toString(); if (msg.contains('GoogleSignInExceptionCode.canceled') || msg.contains('The user canceled') || msg.contains('sign-in flow.') || msg.contains('sign-in sflow.') || msg.contains('Exception: Sign-in was canceled')) { return 'Sign-in was canceled.'; } if (msg.contains('no_network') || msg.contains('network error') || msg.contains('Network connection lost')) { return 'Check your internet connection and try again.'; } if (msg.contains('No active configuration') || msg.contains('GIDClientID')) { return 'Google Sign-In is not configured correctly for this app.'; } if (msg.contains('sign_in_failed') || msg.contains('invalid credentials') || msg.contains('Authentication error')) { return 'Could not sign in with Google. Please try again.'; } if (msg.contains('popup_closed_by_user') || msg.contains('User closed the popup')) { return 'Google sign-in was closed before completion.'; } return 'Google authentication failed.'; }