firebase_phone_number_verification 0.0.1 copy "firebase_phone_number_verification: ^0.0.1" to clipboard
firebase_phone_number_verification: ^0.0.1 copied to clipboard

PlatformAndroid

A Flutter plugin for Firebase Phone Number Verification (PNV) on Android. Verify the device's phone number directly from the carrier with one tap, without SMS OTPs.

example/lib/main.dart

import 'package:firebase_phone_number_verification/firebase_phone_number_verification.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Firebase PNV Example',
      theme: ThemeData(
        colorSchemeSeed: Colors.deepOrange,
        useMaterial3: true,
      ),
      home: const PnvDemoPage(),
    );
  }
}

class PnvDemoPage extends StatefulWidget {
  const PnvDemoPage({super.key});

  @override
  State<PnvDemoPage> createState() => _PnvDemoPageState();
}

class _PnvDemoPageState extends State<PnvDemoPage> {
  final _fpnv = FirebasePhoneNumberVerification.instance;
  final _testNumberIdController = TextEditingController();

  bool _testSessionEnabled = false;
  bool _busy = false;
  List<VerificationSupportResult>? _supportResults;
  VerifiedPhoneNumberResult? _verificationResult;
  String? _error;

  Future<void> _run(Future<void> Function() action) async {
    setState(() {
      _busy = true;
      _error = null;
    });
    try {
      await action();
    } on FirebasePnvException catch (e) {
      setState(() => _error = '${e.code.name}: ${e.message}');
    } finally {
      if (mounted) setState(() => _busy = false);
    }
  }

  Future<void> _enableTestSession() => _run(() async {
        await _fpnv.enableTestSession(_testNumberIdController.text.trim());
        setState(() => _testSessionEnabled = true);
      });

  Future<void> _checkSupport() => _run(() async {
        final results = await _fpnv.getVerificationSupportInfo();
        setState(() => _supportResults = results);
      });

  Future<void> _verify() => _run(() async {
        final result = await _fpnv.getVerifiedPhoneNumber();
        setState(() => _verificationResult = result);
      });

  @override
  void dispose() {
    _testNumberIdController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Firebase PNV Example')),
      body: ListView(
        padding: const EdgeInsets.all(16),
        children: [
          Text(
            '1. Test session (optional)',
            style: Theme.of(context).textTheme.titleMedium,
          ),
          const SizedBox(height: 8),
          const Text(
            'Generate a test number ID in the Firebase console under '
            'Security > Phone Verification > Testing, and paste it here to '
            'try the flow without a real SIM.',
          ),
          const SizedBox(height: 8),
          TextField(
            controller: _testNumberIdController,
            enabled: !_testSessionEnabled,
            decoration: const InputDecoration(
              labelText: 'Test number ID',
              border: OutlineInputBorder(),
            ),
          ),
          const SizedBox(height: 8),
          FilledButton.tonal(
            onPressed: _busy || _testSessionEnabled ? null : _enableTestSession,
            child: Text(
              _testSessionEnabled
                  ? 'Test session enabled'
                  : 'Enable test session',
            ),
          ),
          const Divider(height: 32),
          Text(
            '2. Check support',
            style: Theme.of(context).textTheme.titleMedium,
          ),
          const SizedBox(height: 8),
          FilledButton.tonal(
            onPressed: _busy ? null : _checkSupport,
            child: const Text('Check verification support'),
          ),
          if (_supportResults != null) ...[
            const SizedBox(height: 8),
            for (final r in _supportResults!)
              Card(
                child: ListTile(
                  leading: Icon(
                    r.isSupported ? Icons.check_circle : Icons.cancel,
                    color: r.isSupported ? Colors.green : Colors.red,
                  ),
                  title: Text('SIM slot ${r.simSlot}'),
                  subtitle: Text(
                    'Carrier: ${r.carrierId.isEmpty ? '(unknown)' : r.carrierId}'
                    ' • reason: ${r.reason}',
                  ),
                ),
              ),
            if (_supportResults!.isEmpty)
              const Text('No SIM support info returned.'),
          ],
          const Divider(height: 32),
          Text(
            '3. Verify phone number',
            style: Theme.of(context).textTheme.titleMedium,
          ),
          const SizedBox(height: 8),
          FilledButton(
            onPressed: _busy ? null : _verify,
            child: _busy
                ? const SizedBox(
                    height: 20,
                    width: 20,
                    child: CircularProgressIndicator(strokeWidth: 2),
                  )
                : const Text('Get verified phone number'),
          ),
          if (_verificationResult != null) ...[
            const SizedBox(height: 8),
            Card(
              child: Padding(
                padding: const EdgeInsets.all(16),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      'Verified: ${_verificationResult!.phoneNumber}',
                      style: Theme.of(context).textTheme.titleMedium,
                    ),
                    const SizedBox(height: 8),
                    Text('Issued at: ${_verificationResult!.issuedAt}'),
                    Text('Expires at: ${_verificationResult!.expiresAt}'),
                    const SizedBox(height: 8),
                    Text(
                      'Token: ${_verificationResult!.token}',
                      maxLines: 4,
                      overflow: TextOverflow.ellipsis,
                      style: Theme.of(context).textTheme.bodySmall,
                    ),
                  ],
                ),
              ),
            ),
          ],
          if (_error != null) ...[
            const SizedBox(height: 16),
            Card(
              color: Theme.of(context).colorScheme.errorContainer,
              child: Padding(
                padding: const EdgeInsets.all(16),
                child: Text(
                  _error!,
                  style: TextStyle(
                    color: Theme.of(context).colorScheme.onErrorContainer,
                  ),
                ),
              ),
            ),
          ],
        ],
      ),
    );
  }
}
2
likes
160
points
43
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A Flutter plugin for Firebase Phone Number Verification (PNV) on Android. Verify the device's phone number directly from the carrier with one tap, without SMS OTPs.

Repository (GitHub)
View/report issues

Topics

#firebase #phone-number-verification #authentication #otp #android

License

MIT (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on firebase_phone_number_verification

Packages that implement firebase_phone_number_verification