dot_auth 1.1.0 copy "dot_auth: ^1.1.0" to clipboard
dot_auth: ^1.1.0 copied to clipboard

A powerful Flutter authentication package with phone OTP and email/password verification using Firebase. Plug-and-play, Riverpod-powered, go_router-ready.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:go_router/go_router.dart';
import 'package:animations/animations.dart';
import 'package:dot_auth/dot_auth.dart';

// ─── Config ────────────────────────────────────────────────────────────────

/// Flip to false for phone-only mode.
/// When false, /email is not registered and the phone toggle is hidden.
const bool kEmailEnabled = true;

// ─── Router ────────────────────────────────────────────────────────────────

final routerProvider = Provider<GoRouter>((ref) {
  final routerNotifier = RouterNotifier(ref);

  return GoRouter(
    initialLocation: '/phone',
    refreshListenable: routerNotifier,
    redirect: (context, state) {
      final isAuthenticated = ref.read(authStateProvider).isAuthenticated;

      final isAuthPage = state.matchedLocation == '/phone' ||
          state.matchedLocation == '/otp' ||
          state.matchedLocation == '/email';

      if (isAuthenticated && isAuthPage) return '/home';
      if (!isAuthenticated && state.matchedLocation == '/home') return '/phone';
      return null;
    },
    routes: [
      GoRoute(
        path: '/phone',
        name: 'phone',
        pageBuilder: (context, state) => _slide(
          state,
          const AuthPhone(
            emailEnabled: kEmailEnabled,
            termsRoute: '/terms',
            privacyRoute: '/privacy',
          ),
        ),
      ),
      GoRoute(
        path: '/otp',
        name: 'otp',
        pageBuilder: (context, state) => _slide(state, const OtpScreen()),
      ),
      if (kEmailEnabled)
        GoRoute(
          path: '/email',
          name: 'email',
          pageBuilder: (context, state) => _slide(
            state,
            const AuthEmail(
              phoneEnabled: true,
              termsRoute: '/terms',
              privacyRoute: '/privacy',
            ),
          ),
        ),
      GoRoute(
        path: '/home',
        name: 'home',
        pageBuilder: (context, state) =>
            _slide(state, const _HomeScreen()),
      ),
      GoRoute(
        path: '/terms',
        name: 'terms',
        builder: (_, __) => const _StaticScreen(title: 'Terms & Conditions'),
      ),
      GoRoute(
        path: '/privacy',
        name: 'privacy',
        builder: (_, __) => const _StaticScreen(title: 'Privacy Policy'),
      ),
    ],
  );
});

CustomTransitionPage<void> _slide(GoRouterState state, Widget child) {
  return CustomTransitionPage(
    key: state.pageKey,
    child: child,
    transitionsBuilder: (context, animation, secondaryAnimation, child) {
      return SharedAxisTransition(
        animation: animation,
        secondaryAnimation: secondaryAnimation,
        transitionType: SharedAxisTransitionType.horizontal,
        child: child,
      );
    },
  );
}

// ─── App ───────────────────────────────────────────────────────────────────

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(const ProviderScope(child: _App()));
}

class _App extends ConsumerWidget {
  const _App();

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return ScreenUtilInit(
      designSize: const Size(375, 812),
      builder: (_, __) => MaterialApp.router(
        title: 'dot_auth example',
        theme: authTheme(),
        routerConfig: ref.watch(routerProvider),
      ),
    );
  }
}

// ─── Home screen ───────────────────────────────────────────────────────────

class _HomeScreen extends ConsumerWidget {
  const _HomeScreen();

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final user = ref.watch(currentUserProvider);

    return Scaffold(
      backgroundColor: AuthColors.white,
      appBar: AppBar(
        title: Text('Home', style: AuthTextStyles.headlineS),
        actions: [
          IconButton(
            icon: const Icon(Icons.logout),
            onPressed: () =>
                ref.read(authStateProvider.notifier).signOut(),
          ),
        ],
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Signed in ✓', style: AuthTextStyles.titleM),
            SizedBox(height: 8.h),
            if (user?.phoneNumber != null)
              Text(user!.phoneNumber!, style: AuthTextStyles.bodyM),
            if (user?.email != null)
              Text(user!.email!, style: AuthTextStyles.bodyM),
          ],
        ),
      ),
    );
  }
}

// ─── Static placeholder screen for T&C / Privacy ───────────────────────────

class _StaticScreen extends StatelessWidget {
  final String title;
  const _StaticScreen({required this.title});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: AuthColors.white,
      appBar: AppBar(
        title: Text(title, style: AuthTextStyles.headlineS),
      ),
      body: Center(
        child: Text(
          'Add your $title content here.',
          style: AuthTextStyles.bodyM,
        ),
      ),
    );
  }
}
1
likes
160
points
271
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A powerful Flutter authentication package with phone OTP and email/password verification using Firebase. Plug-and-play, Riverpod-powered, go_router-ready.

Repository (GitHub)

License

MIT (license)

Dependencies

animations, firebase_auth, firebase_core, flutter, flutter_form_builder, flutter_riverpod, flutter_screenutil, form_builder_validators, go_router, google_fonts, phone_form_field, pinput

More

Packages that depend on dot_auth