layou_auth 1.0.0
layou_auth: ^1.0.0 copied to clipboard
Firebase Auth package with Google, Apple, and Email sign-in/linking support. Provides ready-to-use widgets and Riverpod providers.
LayouAuth #
Firebase Auth package with Google, Apple, and Email sign-in/linking support. Provides ready-to-use widgets and Riverpod providers.
Features #
- 🔐 Sign-in methods: Anonymous, Google, Apple, Email/Password
- 🔗 Account linking: Link anonymous accounts to providers
- 🎨 Customizable UI: Use default widgets or build your own
- 📦 Riverpod providers: Ready-to-use state management
- 🌍 i18n ready: Easy string customization
- ⚡ Type-safe: Full Dart 3 support with sealed classes
Installation #
Add to your pubspec.yaml:
dependencies:
layou_auth:
path: ../layou_auth # or publish to pub.dev
Setup #
1. Initialize Firebase (as usual) #
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
// ... LayouAuth init below
}
2. Initialize LayouAuth #
import 'package:layou_auth/layou_auth.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
LayouAuth.initialize(
config: LayouAuthConfig(
providers: [
GoogleProviderConfig(
iosClientId: DefaultFirebaseOptions.ios.iosClientId,
),
const AppleProviderConfig(),
const EmailProviderConfig(passwordMinLength: 8),
],
// Optional callbacks
onSignedIn: (user, method) async {
print('User signed in: ${user.uid}');
// Create user in Firestore, track analytics, etc.
},
onAccountLinked: (user, method) async {
print('Account linked with $method');
// Award bonus credits, etc.
},
),
);
runApp(const ProviderScope(child: MyApp()));
}
Usage #
Option 1: Use the default bottom sheet #
// Show link account sheet
LayouAuthSheet.show(
context,
mode: LayouAuthMode.link,
onSuccess: (user, method) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Linked with $method!')),
);
},
);
// Show sign-in sheet
LayouAuthSheet.show(
context,
mode: LayouAuthMode.signIn,
);
Option 2: Use with custom strings (i18n) #
LayouAuthSheet.show(
context,
mode: LayouAuthMode.link,
strings: LayouAuthStrings(
linkAccountTitle: t.auth.linkTitle,
linkAccountSubtitle: t.auth.linkSubtitle,
googleButton: t.auth.continueWithGoogle,
appleButton: t.auth.continueWithApple,
emailButton: t.auth.continueWithEmail,
),
);
Option 3: Full custom UI with builder #
LayouAuthSheet.show(
context,
builder: (context, state, actions) {
return MyCustomAuthSheet(
isLoading: state.isLoading,
hasGoogle: state.hasGoogle,
hasApple: state.hasApple,
error: state.error,
onGoogleTap: actions.linkWithGoogle,
onAppleTap: actions.linkWithApple,
onEmailSubmit: (email, password) =>
actions.linkWithEmail(email, password),
);
},
);
Option 4: Inline section (for settings page) #
class SettingsPage extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
return Column(
children: [
LayouAuthSection(
title: 'Link Account',
subtitle: 'Secure your data and get 5 bonus credits',
onEmailPressed: () => context.push('/link-email'),
onSuccess: (user, method) async {
await creditsService.addBonus(5);
showSuccessSnackbar('Account linked! +5 credits');
},
),
],
);
}
}
Option 5: Individual buttons #
Column(
children: [
LayouGoogleButton(
label: 'Continue with Google',
onPressed: () async {
final result = await ref
.read(layouAuthActionsProvider.notifier)
.linkWithGoogle();
result.when(
success: (user) => print('Linked!'),
error: (e) => print('Error: $e'),
);
},
),
LayouAppleButton(
label: 'Continue with Apple',
onPressed: () => ref
.read(layouAuthActionsProvider.notifier)
.linkWithApple(),
),
LayouEmailForm(
onSubmit: (email, password) async {
await ref
.read(layouAuthActionsProvider.notifier)
.linkWithEmail(email: email, password: password);
},
),
],
)
Riverpod Providers #
// Watch current user
final user = ref.watch(layouCurrentUserProvider);
// Check auth state
final isAuthenticated = ref.watch(layouIsAuthenticatedProvider);
final isAnonymous = ref.watch(layouIsAnonymousProvider);
// Check linked providers
final hasGoogle = ref.watch(layouHasGoogleProvider);
final hasApple = ref.watch(layouHasAppleProvider);
final hasEmail = ref.watch(layouHasEmailProvider);
final providers = ref.watch(layouLinkedProvidersProvider);
// Auth stream
final authStream = ref.watch(layouAuthStateProvider);
// Perform actions
final actions = ref.read(layouAuthActionsProvider.notifier);
await actions.signInAnonymously();
await actions.signInWithGoogle();
await actions.linkWithGoogle();
await actions.signOut();
await actions.deleteUser();
Direct Service Access #
// Access the service directly
final service = LayouAuth.auth;
// Or via provider
final service = ref.read(layouAuthServiceProvider);
// Use service methods
final result = await service.signInAnonymously();
result.when(
success: (user) => print('Signed in as ${user.uid}'),
error: (e) => print('Error: $e'),
);
Error Handling #
All auth exceptions extend AuthException:
sealed class AuthException implements Exception {
final String message;
final String? code;
}
// Specific exceptions:
UserCancelledException
NoUserException
SignInFailedException
LinkingFailedException
CredentialAlreadyInUseException
EmailAlreadyInUseException
WeakPasswordException
InvalidEmailException
UserNotFoundException
WrongPasswordException
UserDisabledException
NetworkException
UnknownAuthException
Theme Customization #
LayouAuthSheet.show(
context,
theme: LayouAuthTheme(
googleButtonStyle: OutlinedButton.styleFrom(...),
appleButtonStyle: ElevatedButton.styleFrom(...),
buttonBorderRadius: 16.0,
buttonSpacing: 16.0,
),
);
Platform Setup #
Google Sign-In #
- Add
GoogleService-Info.plist(iOS) andgoogle-services.json(Android) - Pass the iOS client ID to the config:
GoogleProviderConfig(iosClientId: 'xxx.apps.googleusercontent.com')
Apple Sign-In #
- Enable "Sign in with Apple" capability in Xcode
- Configure in Apple Developer Console
- No code config needed - just add
AppleProviderConfig()
Email/Password #
No special setup needed - just add EmailProviderConfig().
Migration Guide #
From existing auth code #
- Replace your
AuthRepositorywithLayouAuth.auth - Replace your providers with
layouAuthStateProvider, etc. - Move Firestore user creation to
onSignedIncallback - Replace UI widgets with
LayouAuthSheetor use builder for custom UI
License #
MIT