bloc_firebase_auth_kit 1.0.0
bloc_firebase_auth_kit: ^1.0.0 copied to clipboard
A clean architecture Flutter package for Firebase authentication with BLoC state management, supporting email/password, Google, Facebook sign-in, and more.
bloc_firebase_auth_kit #
A clean architecture Flutter package for Firebase authentication with BLoC state management, supporting email/password, Google, Facebook sign-in, and more.
Features #
β¨ Multiple Authentication Methods
- Email/Password authentication
- Google Sign-In
- Facebook authentication
- Easy to extend for additional providers
ποΈ Clean Architecture
- Separation of concerns with Domain, Data, and Presentation layers
- Repository pattern for data access
- Use cases for business logic
π― BLoC State Management
- Predictable state management using flutter_bloc
- Reactive authentication flows
- Easy integration with existing BLoC apps
π¨ Pre-built UI Components
- Ready-to-use sign-in form
- Social sign-in buttons
- Auth state wrapper widget
π Persistent Authentication
- Local storage of auth state
- Automatic user restoration on app restart
π± Multi-platform Support
- Android
- iOS
- Web
Installation #
Add this to your package's pubspec.yaml file:
dependencies:
bloc_firebase_auth_kit: ^1.0.0
Then run:
flutter pub get
Prerequisites #
Before using this package, you need to:
- Create a Firebase project at Firebase Console
- Enable authentication providers in Firebase Console:
- Email/Password
- Google Sign-In
- Facebook (optional)
- Add Firebase configuration files to your app (see Platform Setup below)
Quick Start #
1. Initialize Firebase #
import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart'; // Generated by FlutterFire CLI
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
runApp(MyApp());
}
2. Initialize the Auth Service Locator #
import 'package:bloc_firebase_auth_kit/bloc_firebase_auth_kit.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
// Initialize auth dependencies
await AuthServiceLocator.init();
runApp(MyApp());
}
3. Setup Dependency Injection (Optional) #
If you're using your own dependency injection setup:
import 'package:get_it/get_it.dart';
import 'package:bloc_firebase_auth_kit/bloc_firebase_auth_kit.dart';
final getIt = GetIt.instance;
Future<void> setupDI() async {
// Initialize package's auth services
await AuthServiceLocator.init();
// Register AuthBloc in your DI container
getIt.registerFactory<AuthBloc>(() => AuthBloc(
signInWithEmail: sl<SignInWithEmail>(),
signInWithGoogle: sl<SignInWithGoogle>(),
signInWithFacebook: sl<SignInWithFacebook>(),
signOut: sl<SignOut>(),
getCurrentUser: sl<GetCurrentUser>(),
));
}
4. Provide AuthBloc to Your Widget Tree #
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:bloc_firebase_auth_kit/bloc_firebase_auth_kit.dart';
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => AuthBloc(
signInWithEmail: sl<SignInWithEmail>(),
signInWithGoogle: sl<SignInWithGoogle>(),
signInWithFacebook: sl<SignInWithFacebook>(),
signOut: sl<SignOut>(),
getCurrentUser: sl<GetCurrentUser>(),
)..add(AuthCheckRequested()),
child: MaterialApp(
home: AuthWrapper(
signedInBuilder: (context, user) => HomePage(user: user),
signedOutBuilder: (context) => LoginPage(),
),
),
);
}
}
Usage Examples #
Using the Pre-built Sign-In Form #
import 'package:bloc_firebase_auth_kit/bloc_firebase_auth_kit.dart';
class LoginPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Sign In')),
body: Padding(
padding: EdgeInsets.all(16),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SignInForm(),
SizedBox(height: 20),
SocialSignInButtons(),
],
),
),
);
}
}
Custom Authentication UI #
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:bloc_firebase_auth_kit/bloc_firebase_auth_kit.dart';
class CustomLoginPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: BlocConsumer<AuthBloc, AuthState>(
listener: (context, state) {
if (state is AuthError) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(state.message)),
);
}
},
builder: (context, state) {
if (state is AuthLoading) {
return Center(child: CircularProgressIndicator());
}
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
context.read<AuthBloc>().add(
AuthSignInWithEmailRequested(
email: 'user@example.com',
password: 'password123',
),
);
},
child: Text('Sign In with Email'),
),
SizedBox(height: 16),
ElevatedButton(
onPressed: () {
context.read<AuthBloc>().add(
AuthSignInWithGoogleRequested(),
);
},
child: Text('Sign In with Google'),
),
SizedBox(height: 16),
ElevatedButton(
onPressed: () {
context.read<AuthBloc>().add(
AuthSignInWithFacebookRequested(),
);
},
child: Text('Sign In with Facebook'),
),
],
),
);
},
),
);
}
}
Sign Out #
ElevatedButton(
onPressed: () {
context.read<AuthBloc>().add(AuthSignOutRequested());
},
child: Text('Sign Out'),
)
Access Current User #
BlocBuilder<AuthBloc, AuthState>(
builder: (context, state) {
if (state is AuthAuthenticated) {
final user = state.user;
return Text('Welcome, ${user.displayName ?? user.email}!');
}
return Text('Not signed in');
},
)
Platform Setup #
Android #
- Add your Android app to Firebase Console
- Download
google-services.json - Place it in
android/app/ - Update
android/build.gradle:dependencies { classpath 'com.google.gms:google-services:4.4.0' } - Update
android/app/build.gradle:apply plugin: 'com.google.gms.google-services'
Google Sign-In on Android
Add SHA-1 fingerprint to Firebase Console:
cd android
./gradlew signingReport
iOS #
- Add your iOS app to Firebase Console
- Download
GoogleService-Info.plist - Add it to
ios/Runner/in Xcode - Update
ios/Runner/Info.plist:<key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleURLSchemes</key> <array> <string>YOUR_REVERSED_CLIENT_ID</string> </array> </dict> </array>
Find REVERSED_CLIENT_ID in your GoogleService-Info.plist.
Web #
- Add your Web app to Firebase Console
- For Google Sign-In, add this meta tag to
web/index.html:<head> <meta name="google-signin-client_id" content="YOUR_WEB_CLIENT_ID.apps.googleusercontent.com"> </head>
Note for Web: When running locally, use port 5000 which is whitelisted by default:
flutter run -d chrome --web-port 5000
Add http://localhost:5000 to authorized domains in Firebase Console.
Configuration #
Custom Google Sign-In Configuration #
For web platform, you can pass a custom client ID:
import 'package:google_sign_in/google_sign_in.dart';
import 'package:get_it/get_it.dart';
// Override the GoogleSignIn instance before initializing AuthServiceLocator
GetIt.instance.registerLazySingleton<GoogleSignIn>(
() => GoogleSignIn(
clientId: kIsWeb ? 'YOUR_WEB_CLIENT_ID' : null,
scopes: ['email', 'profile'],
),
);
await AuthServiceLocator.init();
Using Custom Error Handling #
BlocListener<AuthBloc, AuthState>(
listener: (context, state) {
if (state is AuthError) {
// Handle different error types
if (state.message.contains('user-not-found')) {
// Show registration dialog
} else if (state.message.contains('wrong-password')) {
// Show password reset option
} else {
// Generic error handling
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('Authentication Error'),
content: Text(state.message),
),
);
}
}
},
child: YourWidget(),
)
Architecture Overview #
This package follows Clean Architecture principles:
lib/
βββ src/
β βββ core/
β β βββ constants/ # Auth-related constants
β β βββ di/ # Dependency injection setup
β β βββ error/ # Error handling (Failures & Exceptions)
β βββ data/
β β βββ datasources/ # Remote (Firebase) & Local data sources
β β βββ models/ # Data models
β β βββ repositories/ # Repository implementations
β βββ domain/
β β βββ entities/ # Business entities
β β βββ repositories/ # Repository interfaces
β β βββ usecases/ # Business logic use cases
β βββ presentation/
β βββ bloc/ # BLoC state management
β βββ widgets/ # Reusable UI components
API Reference #
AuthBloc Events #
AuthCheckRequested()- Check current auth statusAuthSignInWithEmailRequested({email, password})- Sign in with emailAuthSignInWithGoogleRequested()- Sign in with GoogleAuthSignInWithFacebookRequested()- Sign in with FacebookAuthSignOutRequested()- Sign out current user
AuthBloc States #
AuthInitial- Initial stateAuthLoading- Authentication in progressAuthAuthenticated(user)- User successfully authenticatedAuthUnauthenticated- No authenticated userAuthError(message)- Authentication error occurred
User Entity #
class UserEntity {
final String uid;
final String? email;
final String? displayName;
final String? photoURL;
final bool isEmailVerified;
}
Troubleshooting #
Google Sign-In Issues #
Web: Make sure you've added the meta tag with client ID to index.html and are running on an authorized domain.
Android: Ensure SHA-1 fingerprint is added to Firebase Console.
iOS: Verify REVERSED_CLIENT_ID is correctly added to URL schemes.
Facebook Sign-In Issues #
- Create a Facebook App at developers.facebook.com
- Add Facebook App ID to Firebase Console
- Follow platform-specific setup in flutter_facebook_auth documentation
Common Errors #
PlatformException: sign_in_failed- Check platform-specific configurationFirebaseException: invalid-credential- Verify Firebase project settingsnull-safety error- Ensure all dependencies are up to date
Contributing #
Contributions are welcome! Please feel free to submit a Pull Request.
License #
This project is licensed under the MIT License - see the LICENSE file for details.
Support #
For issues, questions, or suggestions:
- Open an issue on GitHub
- Check existing documentation and examples
Credits #
Built with: