layou_auth 1.0.0 copy "layou_auth: ^1.0.0" to clipboard
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 #

  1. Add GoogleService-Info.plist (iOS) and google-services.json (Android)
  2. Pass the iOS client ID to the config:
    GoogleProviderConfig(iosClientId: 'xxx.apps.googleusercontent.com')
    

Apple Sign-In #

  1. Enable "Sign in with Apple" capability in Xcode
  2. Configure in Apple Developer Console
  3. No code config needed - just add AppleProviderConfig()

Email/Password #

No special setup needed - just add EmailProviderConfig().

Migration Guide #

From existing auth code #

  1. Replace your AuthRepository with LayouAuth.auth
  2. Replace your providers with layouAuthStateProvider, etc.
  3. Move Firestore user creation to onSignedIn callback
  4. Replace UI widgets with LayouAuthSheet or use builder for custom UI

License #

MIT

1
likes
0
points
28
downloads

Publisher

unverified uploader

Weekly Downloads

Firebase Auth package with Google, Apple, and Email sign-in/linking support. Provides ready-to-use widgets and Riverpod providers.

Repository (GitHub)
View/report issues

Topics

#firebase #authentication #riverpod #google-sign-in #apple-sign-in

License

unknown (license)

Dependencies

crypto, firebase_auth, flutter, flutter_riverpod, google_sign_in, riverpod_annotation, sign_in_with_apple

More

Packages that depend on layou_auth