This example demonstrates how to integrate MetaMask Embedded Wallets with Firebase Authentication in a Flutter application. It showcases a custom authentication setup using Firebase as the JWT provider with Web3Auth's blockchain functionality.
- Firebase Authentication: Google Sign-In, Email/Password, Phone Auth
- Custom JWT Authentication: Firebase ID tokens used for Web3Auth login
- EVM Wallet: Automatic Ethereum wallet creation linked to Firebase account
- Blockchain Interactions: Full blockchain operations using web3dart
- Secure Key Management: Non-custodial key management with Firebase identity
- Cross-Platform: Single codebase for iOS and Android
- Persistent Sessions: Firebase + Web3Auth session management
- Flutter: 3.0.0 or higher
- Dart: 2.18.0 or higher
- Firebase Account: Create one here
- MetaMask Embedded Wallets: Dashboard account
- iOS (for iOS development):
- iOS 14+, Xcode 12+, Swift 5.x, CocoaPods
- Android (for Android development):
- API level 26+, compileSdkVersion 34, JDK 11+
-
Clone the repository:
git clone https://github.com/Web3Auth/web3auth-flutter-examples.git cd web3auth-flutter-examples/flutter-firebase-example -
Install dependencies:
flutter pub get
-
iOS Setup (for iOS development):
cd ios && pod install && cd ..
-
Create a Firebase project:
- Go to Firebase Console
- Create a new project or select existing one
- Add iOS and/or Android apps to your project
-
Download configuration files:
- iOS: Download
GoogleService-Info.plistand place inios/Runner/ - Android: Download
google-services.jsonand place inandroid/app/
- iOS: Download
-
Enable Authentication methods:
- In Firebase Console, go to Authentication β Sign-in method
- Enable Google, Email/Password, or other providers you want to use
-
Configure OAuth providers (for Google Sign-In):
- Follow Firebase documentation for platform-specific setup
- Add SHA-1 fingerprint for Android
- Configure OAuth consent screen
-
Create a project on the Embedded Wallets Dashboard
-
Choose your network:
- Sapphire Devnet: For development/testing
- Sapphire Mainnet: For production
-
Create a Custom Authentication connection:
- Go to "Auth" β "Custom Authentication"
- Click "Create Verifier"
- Select "Custom" as the login provider
- Configure Firebase:
- Verifier Name: Give it a unique name (e.g.,
firebase-flutter-verifier) - JWT Verifier ID:
sub(oruser_iddepending on your Firebase token structure) - JWK Endpoint:
https://www.googleapis.com/service_accounts/v1/jwk/securetoken@system.gserviceaccount.com - Validation: Add
issfield with valuehttps://securetoken.google.com/YOUR_FIREBASE_PROJECT_ID
- Verifier Name: Give it a unique name (e.g.,
-
Configure platform settings:
- iOS: Allowlist
{bundleId}://auth - Android: Allowlist your package name
- iOS: Allowlist
-
Get your Client ID and Verifier Name from the dashboard
Update the configuration in lib/main.dart:
import 'package:web3auth_flutter/web3auth_flutter.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'dart:io';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
// Initialize Firebase
await Firebase.initializeApp();
// Initialize Web3Auth
await initWeb3Auth();
runApp(MyApp());
}
Future<void> initWeb3Auth() async {
late final Uri redirectUrl;
if (Platform.isAndroid) {
redirectUrl = Uri.parse('w3a://com.example.firebaseapp/auth');
} else if (Platform.isIOS) {
redirectUrl = Uri.parse('com.example.firebaseapp://auth');
}
await Web3AuthFlutter.init(
Web3AuthOptions(
clientId: "YOUR_WEB3AUTH_CLIENT_ID",
network: Network.sapphire_mainnet,
redirectUrl: redirectUrl,
)
);
await Web3AuthFlutter.initialize();
}# Run in debug mode
flutter run
# Build for release
flutter build ios # For iOS
flutter build apk # For Androidlib/
βββ main.dart # Entry point & initialization
βββ services/
β βββ firebase_service.dart # Firebase Auth operations
β βββ web3auth_service.dart # Web3Auth operations
β βββ blockchain.dart # Blockchain operations
βββ screens/
βββ home.dart # Home screen with wallet info
βββ login.dart # Login screen with Firebase options
import 'package:firebase_core/firebase_core.dart';
import 'package:web3auth_flutter/web3auth_flutter.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
// Initialize Firebase first
await Firebase.initializeApp();
// Then initialize Web3Auth
await initWeb3Auth();
runApp(MyApp());
}import 'package:firebase_auth/firebase_auth.dart';
import 'package:google_sign_in/google_sign_in.dart';
Future<void> loginWithFirebase() async {
try {
// Step 1: Authenticate with Firebase (Google example)
final GoogleSignIn googleSignIn = GoogleSignIn();
final GoogleSignInAccount? googleUser = await googleSignIn.signIn();
if (googleUser == null) return; // User canceled
final GoogleSignInAuthentication googleAuth =
await googleUser.authentication;
final credential = GoogleAuthProvider.credential(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
// Sign in to Firebase
final UserCredential userCredential =
await FirebaseAuth.instance.signInWithCredential(credential);
// Step 2: Get Firebase ID Token
final User? user = userCredential.user;
if (user == null) return;
final String? idToken = await user.getIdToken();
if (idToken == null) return;
// Step 3: Login to Web3Auth with Firebase JWT
final Web3AuthResponse response = await Web3AuthFlutter.login(
LoginParams(
loginProvider: Provider.jwt,
extraLoginOptions: ExtraLoginOptions(
id_token: idToken,
verifierIdField: 'sub', // or 'email' based on your setup
domain: 'firebase', // optional
),
)
);
print('Web3Auth login successful!');
print('User: ${response.userInfo?.email}');
} catch (e) {
print('Login error: $e');
}
}Future<void> loginWithEmailPassword(String email, String password) async {
try {
// Step 1: Sign in with Firebase
final UserCredential userCredential =
await FirebaseAuth.instance.signInWithEmailAndPassword(
email: email,
password: password,
);
// Step 2: Get ID token
final User? user = userCredential.user;
final String? idToken = await user?.getIdToken();
if (idToken == null) return;
// Step 3: Login to Web3Auth
await Web3AuthFlutter.login(
LoginParams(
loginProvider: Provider.jwt,
extraLoginOptions: ExtraLoginOptions(
id_token: idToken,
verifierIdField: 'sub',
),
)
);
} catch (e) {
print('Login error: $e');
}
}Future<void> logout() async {
// Logout from Web3Auth
await Web3AuthFlutter.logout();
// Logout from Firebase
await FirebaseAuth.instance.signOut();
await GoogleSignIn().signOut();
}import 'package:web3dart/web3dart.dart';
Future<void> getWalletInfo() async {
// Get private key from Web3Auth
final privateKey = await Web3AuthFlutter.getPrivKey();
// Create credentials
final credentials = EthPrivateKey.fromHex(privateKey);
// Get address
final address = credentials.address;
print('Wallet address: ${address.hex}');
// Get balance
final client = Web3Client('YOUR_RPC_URL', Client());
final balance = await client.getBalance(address);
print('Balance: ${balance.getValueInUnit(EtherUnit.ether)} ETH');
}- JWT Token Security: Firebase ID tokens are short-lived and automatically refreshed
- Non-Custodial: Private keys derived from Firebase identity using Shamir Secret Sharing
- Firebase Rules: Implement proper Firebase Security Rules for your database/storage
- Token Validation: Web3Auth validates Firebase JWT tokens using JWKS endpoint
- Network Consistency: Never change Client ID or verifier configuration in production
- Same User Identity: Same Firebase user always gets the same wallet address
Problem: Firebase initialization fails
Solutions:
- Verify
google-services.json(Android) is inandroid/app/ - Verify
GoogleService-Info.plist(iOS) is inios/Runner/ - Check that Firebase project ID matches in both files
- Run
flutter cleanand rebuild
Problem: Google Sign-In not working on Android
Solutions:
- Add SHA-1 fingerprint to Firebase Console
- Enable Google Sign-In in Firebase Authentication
- Verify
google-services.jsonis up to date
Problem: JWT login fails with "Invalid token" error
Solutions:
- Verify JWT Verifier configuration in Web3Auth dashboard
- Check that
issfield validation matches:https://securetoken.google.com/YOUR_PROJECT_ID - Ensure JWKS endpoint is correct
- Verify
verifierIdFieldmatches token structure (suboremail) - Check that ID token is fresh (call
getIdToken()right before Web3Auth login)
Problem: Different wallet address on each login
Solutions:
- Ensure you're using the same verifier name each time
- Verify
verifierIdFieldis consistent - Check that Client ID hasn't changed
- Ensure network (devnet/mainnet) is consistent
iOS:
- Add URL scheme to
Info.plist - Allowlist
{bundleId}://authin dashboard - Check that Firebase GoogleService-Info.plist is included in Xcode
Android:
- Configure deep link intent filter in
AndroidManifest.xml - Add SHA-1 to Firebase for Google Sign-In
- Verify
compileSdkVersion 34
- MetaMask Embedded Wallets Docs
- Flutter SDK Reference
- Custom Authentication Guide
- Firebase Flutter Setup
- Firebase Authentication
Need help? Reach out through:
This example is available under the MIT License. See the LICENSE file for more info.