Install
$ agentstack add skill-evanca-flutter-ai-rules-firebase-auth ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Firebase Authentication Skill
This skill defines how to correctly use Firebase Authentication in Flutter applications.
When to Use
Use this skill when:
- Setting up Firebase Authentication in a Flutter project.
- Listening to authentication state changes.
- Implementing email/password, phone number, or social sign-in.
- Managing user profiles, account linking, or MFA.
- Handling authentication errors (including iOS
recaptcha-sdk-not-linkedfor phone auth). - Applying security best practices for auth flows.
1. Setup and Configuration
flutter pub add firebase_auth
import 'package:firebase_auth/firebase_auth.dart';
- Enable desired authentication providers in the Firebase console before using them.
- Initialize Firebase before using any Firebase Authentication features.
Local emulator for testing:
Future main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
await FirebaseAuth.instance.useAuthEmulator('localhost', 9099);
// ...
}
2. Authentication State Management
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!');
}
});
- Listen to these streams immediately when the app starts to handle the initial auth state.
- Custom claims are only available after sign-in, re-authentication, token expiration, or manual token refresh.
3. Email and Password Authentication
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.');
}
}
- Verify the user's email address after account creation.
- Firebase rate-limits new email/password sign-ups from the same IP to protect against abuse.
- On iOS/macOS, authentication state persists between app re-installs via the system keychain.
- Since September 2023, Firebase enables email enumeration protection by default on new projects, replacing
user-not-foundandwrong-passwordwithinvalid-credential. Manage this in the Firebase console under Authentication > Settings. - When email enumeration protection is enabled,
sendPasswordResetEmail()may complete without an error even if the email is not registered. Treat this as expected behavior and do not use password-reset responses to infer whether an email exists.
4. Social Authentication
Google Sign-In (native platforms):
Future 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 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);
}
- Configure platform-specific settings for each provider (e.g., SHA1 key for Google Sign-In on Android).
- If a user signs in with a social provider after registering with the same email manually, Firebase's trusted provider concept will automatically change their authentication provider.
- On Android,
signInWithProvideropens a Chrome Custom Tab. IfAndroidManifest.xmlcontainsandroid:taskAffinity=""(Flutter's default), the tab closes when the user switches apps (e.g., to use a password manager), causing aweb-context-already-presentederror. Removeandroid:taskAffinity=""to fix this. - When signing in with Apple, add the
emailandnamescopes to present the full first-time sign-in UI (including "Share/Hide email"):
``dart final appleProvider = AppleAuthProvider(); appleProvider.addScope('email'); appleProvider.addScope('name'); ``
- To revoke Apple auth tokens after sign-in, use the appropriate API per platform:
- Apple platforms (iOS/macOS/web): use
revokeTokenWithAuthorizationCode()with the authorization code fromuserCredential.additionalUserInfo?.authorizationCode. - Android: use
revokeAccessToken()with the access token fromuserCredential.credential?.accessToken.
```dart // 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); } ```
5. Phone Number Authentication
Before using phone authentication, ensure platform-specific prerequisites are met:
- Android: SHA-1 hashes must be configured in the Firebase console and Google Play Integrity API enabled.
- iOS: APNs authentication key must be configured with FCM and background modes for remote notifications enabled.
- Web: Add your application's domain to the Firebase console under OAuth redirect domains.
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:
- Recommended: Link the reCAPTCHA Enterprise iOS SDK in Xcode following Google's guide.
- Alternative: Disable reCAPTCHA SMS defense via the Identity Toolkit
projects.updateConfigREST API (setrecaptchaConfig.phoneEnforcementStatetoOFFandrecaptchaConfig.useSmsTollFraudProtectiontofalse). See the official steps. This reduces fraud protection — prefer linking the SDK. - If the SDK uses a Safari view controller-hosted challenge, handle the return URL using
uni_links/app_linksorapplication:openURL:in the iOS runner.
6. Error Handling
- Always use
try-catchwithFirebaseAuthException. - Check
e.codeto identify specific error types. - Handle
account-exists-with-different-credentialby fetching sign-in methods for the email and guiding users through the correct flow. - Handle
too-many-requestswith retry logic or user feedback. - Handle
operation-not-allowedby ensuring the provider is enabled in the Firebase console. - On iOS,
recaptcha-sdk-not-linkedduringverifyPhoneNumberis raised by the native Firebase iOS Auth SDK and requires native setup or GCP configuration changes — it cannot be fixed from Dart code alone.
7. User Management
// 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");
- Use
verifyBeforeUpdateEmail()— notupdateEmail()— to change a user's email. The email only updates after the user verifies it. - Store only essential info in the auth profile; use a database for additional user data.
- Use
linkWithCredential()to connect multiple auth providers to a single account. - Verify the user's identity before linking new credentials.
- Use
fetchSignInMethodsForEmail()when handling account linking.
8. Security Best Practices
- Never store sensitive authentication credentials in client-side code.
- Monitor auth state changes for proper session management.
- Validate user input before submitting authentication requests to prevent injection attacks.
- Call
FirebaseAuth.instance.signOut()when users exit the app. - For sensitive operations, re-authenticate users with
reauthenticateWithCredential(). - Enforce strong password policies for email/password auth.
- In Realtime Database and Cloud Storage Security Rules, use the
authvariable to get the signed-in user's UID for access control. - Use multi-factor authentication for sensitive applications.
9. Multi-Factor Authentication
> 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.
- Enable at least one MFA-compatible provider before implementing MFA.
10. Email Link Authentication
> Important: Firebase Dynamic Links is deprecated for email link authentication. Firebase Hosting is now used to send sign-in links.
- Set
handleCodeInApp: trueinActionCodeSettings— sign-in must always be completed in the app. - Store the user's email locally (e.g.,
SharedPreferences) when sending the sign-in link. - Never pass the user's email in redirect URL parameters — this enables session injection attacks.
- Use HTTPS URLs in production to prevent link interception.
- Configure the app to detect incoming links and parse the underlying deep link for sign-in completion.
References
- Firebase Authentication Flutter documentation
- Email/password authentication
- Federated identity & social sign-in
- Multi-factor authentication
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: evanca
- Source: evanca/flutter-ai-rules
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.