一键导入
firebase-auth
// Integrates Firebase Authentication into Flutter apps. Use when setting up auth, managing auth state, implementing email/password or social sign-in, handling auth errors, managing users, or applying security best practices.
// Integrates Firebase Authentication into Flutter apps. Use when setting up auth, managing auth state, implementing email/password or social sign-in, handling auth errors, managing users, or applying security best practices.
| name | firebase-auth |
| description | Integrates Firebase Authentication into Flutter apps. Use when setting up auth, managing auth state, implementing email/password or social sign-in, handling auth errors, managing users, or applying security best practices. |
This skill defines how to correctly use Firebase Authentication in Flutter applications.
Use this skill when:
recaptcha-sdk-not-linked for phone auth).flutter pub add firebase_auth
import 'package:firebase_auth/firebase_auth.dart';
Local emulator for testing:
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
await FirebaseAuth.instance.useAuthEmulator('localhost', 9099);
// ...
}
Use the appropriate stream based on what you need to observe:
| Stream | Fires when |
|---|---|
authStateChanges() | User signs in or out |
idTokenChanges() | ID token changes (including custom claims) |
userChanges() | User data changes (e.g., profile updates) |
FirebaseAuth.instance
.authStateChanges()
.listen((User? user) {
if (user == null) {
print('User is currently signed out!');
} else {
print('User is signed in!');
}
});
Create a new account:
try {
final credential = await FirebaseAuth.instance.createUserWithEmailAndPassword(
email: emailAddress,
password: password,
);
} on FirebaseAuthException catch (e) {
if (e.code == 'weak-password') {
print('The password provided is too weak.');
} else if (e.code == 'email-already-in-use') {
print('The account already exists for that email.');
}
} catch (e) {
print(e);
}
Sign in:
try {
final credential = await FirebaseAuth.instance.signInWithEmailAndPassword(
email: emailAddress,
password: password,
);
} on FirebaseAuthException catch (e) {
if (e.code == 'invalid-credential') {
// Email enumeration protection enabled (default since Sep 2023):
// replaces 'user-not-found' and 'wrong-password'.
print('Invalid email or password.');
} else if (e.code == 'user-not-found') {
print('No user found for that email.');
} else if (e.code == 'wrong-password') {
print('Wrong password provided for that user.');
}
}
user-not-found and wrong-password with invalid-credential. Manage this in the Firebase console under Authentication > Settings.Google Sign-In (native platforms):
Future<UserCredential> signInWithGoogle() async {
final GoogleSignInAccount? googleUser = await GoogleSignIn.instance.authenticate();
final GoogleSignInAuthentication googleAuth = googleUser.authentication;
final credential = GoogleAuthProvider.credential(idToken: googleAuth.idToken);
return await FirebaseAuth.instance.signInWithCredential(credential);
}
Google Sign-In (web):
Future<UserCredential> signInWithGoogle() async {
GoogleAuthProvider googleProvider = GoogleAuthProvider();
googleProvider.addScope('https://www.googleapis.com/auth/contacts.readonly');
googleProvider.setCustomParameters({'login_hint': 'user@example.com'});
return await FirebaseAuth.instance.signInWithPopup(googleProvider);
}
signInWithProvider opens a Chrome Custom Tab. If AndroidManifest.xml contains android:taskAffinity="" (Flutter's default), the tab closes when the user switches apps (e.g., to use a password manager), causing a web-context-already-presented error. Remove android:taskAffinity="" to fix this.email and name scopes to present the full first-time sign-in UI (including "Share/Hide email"):
final appleProvider = AppleAuthProvider();
appleProvider.addScope('email');
appleProvider.addScope('name');
revokeTokenWithAuthorizationCode() with the authorization code from userCredential.additionalUserInfo?.authorizationCode.revokeAccessToken() with the access token from userCredential.credential?.accessToken.// Apple platforms (iOS/macOS/web)
final authCode = userCredential.additionalUserInfo?.authorizationCode;
if (authCode != null) {
await FirebaseAuth.instance.revokeTokenWithAuthorizationCode(authCode);
}
// Android
final accessToken = userCredential.credential?.accessToken;
if (accessToken != null) {
await FirebaseAuth.instance.revokeAccessToken(accessToken);
}
Before using phone authentication, ensure platform-specific prerequisites are met:
Phone number sign-in is only supported on real devices and the web. Testing on device emulators is not supported.
iOS: recaptcha-sdk-not-linked error
On iOS, verifyPhoneNumber can throw FirebaseAuthException with code recaptcha-sdk-not-linked when Identity Platform expects reCAPTCHA Enterprise but the native SDK is not linked. This cannot be resolved from Dart — fix it at the native iOS or GCP level:
projects.updateConfig REST API (set recaptchaConfig.phoneEnforcementState to OFF and recaptchaConfig.useSmsTollFraudProtection to false). See the official steps. This reduces fraud protection — prefer linking the SDK.uni_links/app_links or application:openURL: in the iOS runner.try-catch with FirebaseAuthException.e.code to identify specific error types.account-exists-with-different-credential by fetching sign-in methods for the email and guiding users through the correct flow.too-many-requests with retry logic or user feedback.operation-not-allowed by ensuring the provider is enabled in the Firebase console.recaptcha-sdk-not-linked during verifyPhoneNumber is raised by the native Firebase iOS Auth SDK and requires native setup or GCP configuration changes — it cannot be fixed from Dart code alone.// Update profile
await FirebaseAuth.instance.currentUser?.updateProfile(
displayName: "Jane Q. User",
photoURL: "https://example.com/jane-q-user/profile.jpg",
);
// Update email (sends verification to new address first)
await user?.verifyBeforeUpdateEmail("newemail@example.com");
verifyBeforeUpdateEmail() — not updateEmail() — to change a user's email. The email only updates after the user verifies it.linkWithCredential() to connect multiple auth providers to a single account.fetchSignInMethodsForEmail() when handling account linking.FirebaseAuth.instance.signOut() when users exit the app.reauthenticateWithCredential().auth variable to get the signed-in user's UID for access control.Security warning: Avoid SMS-based MFA. SMS is insecure and easy to compromise or spoof.
Platform limitation: Windows does not support MFA. MFA with multiple tenants is not supported on Flutter.
Important: Firebase Dynamic Links is deprecated for email link authentication. Firebase Hosting is now used to send sign-in links.
handleCodeInApp: true in ActionCodeSettings — sign-in must always be completed in the app.SharedPreferences) when sending the sign-in link.Structure Flutter apps using layered architecture (UI / Logic / Data) with feature-first file organization. Use when creating new features, designing the project folder structure, adding repositories, services, view models (or cubits/providers/notifiers), wiring dependency injection, or deciding which layer owns a piece of logic. State management agnostic.
Implement Flutter state management using the bloc and flutter_bloc libraries. Use when creating a new Cubit or Bloc, modeling state with sealed classes or status enums, wiring BlocBuilder/BlocListener/BlocProvider in widgets, writing bloc unit tests, refactoring state management, or deciding between Cubit and Bloc.
Review Flutter/Dart pull requests and merge requests against a structured checklist. Use when asked to review a PR, review a MR, review a branch, audit changed files, check code quality, or evaluate a diff. Covers correctness, security, performance, style, testing, and documentation.
Apply Dart 3 language features including patterns, sealed classes, switch expressions, records, and if-case syntax. Use when writing switch statements, refactoring if-else chains, creating data classes, choosing between records and classes, destructuring values, or modernizing pre-Dart-3 code.
Apply Effective Dart guidelines to write idiomatic, high-quality Dart and Flutter code. Use when writing new Dart code, reviewing pull requests for style compliance, refactoring naming conventions, adding doc comments, structuring imports, enforcing type annotations, or running code review checks against Effective Dart standards.
Integrate Firebase AI Logic into Flutter apps using the Gemini Developer API. Use when setting up the firebase_ai plugin, generating text or chat responses with Gemini models, streaming AI output, implementing multimodal prompts, handling AI service errors, or applying security and privacy considerations for AI features.