Skip to main content

Command Palette

Search for a command to run...

Firebase

Updated
•7 min read•View as Markdown
Firebase

How to Integrate Firebase Authentication in a Flutter App: Step-by-Step Guide

Step-by-Step Guide

  1. Set Up Firebase:

    • Go to the Firebase Console.

    • Create a new project.

    • Add an Android/iOS app to your Firebase project and follow the instructions to download the google-services.json (for Android) or GoogleService-Info.plist (for iOS).

    • Enable Firebase Authentication in the Firebase console and choose the authentication method you want (e.g., Email/Password).

  2. Add Dependencies: Update your pubspec.yaml to include the necessary Firebase dependencies:

     dependencies:
       flutter:
         sdk: flutter
       firebase_core: ^2.14.0
       firebase_auth: ^6.19.0
    

    Run flutter pub get to install the new dependencies.

  3. Init****ialize Firebase: Modify your main.dart to initialize Firebase.

Updated main.dart

import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart'; // Import Firebase core
import 'pages/login.dart';
import 'pages/register.dart';
import 'pages/pay_bills.dart';
import 'pages/send_money.dart';
import 'pages/dashboard.dart';
import 'pages/buy_airtime.dart';
import 'pages/withdraw.dart';
import 'pages/bank_transfer.dart';
import 'pages/deposit.dart';
import 'pages/savings_page.dart'; // Import for SavingsPage
import 'pages/loan_page.dart';     // Import for LoanPage
import 'pages/account_page.dart';   // Import for AccountPage

void main() async {
  WidgetsFlutterBinding.ensureInitialized(); // Ensure binding is initialized
  await Firebase.initializeApp(); // Initialize Firebase
  runApp(PocketBankingApp()); // Run the app
}

class PocketBankingApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Pocket Banking',
      theme: ThemeData(
        primarySwatch: Colors.teal,
      ),
      initialRoute: '/',
      routes: {
        '/': (context) => LoginPage(), // Login page as the initial route
        '/dashboard': (context) => DashboardPage(), // Dashboard page route
        '/register': (context) => RegisterPage(), // Register page route
        // Other routes...
      },
    );
  }
}

Updated login.dart

Here's how to update the LoginPage to handle authentication:

import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart'; // Import Firebase Auth

// Defining the LoginPage class
class LoginPage extends StatefulWidget {
  @override
  _LoginPageState createState() => _LoginPageState();
}

class _LoginPageState extends State<LoginPage> {
  // Controllers for email and password fields
  final TextEditingController emailController = TextEditingController();
  final TextEditingController passwordController = TextEditingController();

  // Key to manage the form validation
  final _formKey = GlobalKey<FormState>();
  final FirebaseAuth _auth = FirebaseAuth.instance; // Firebase Auth instance

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Login to PocketWallet', style: TextStyle(color: Colors.white)), // AppBar title
        backgroundColor: Colors.teal, // AppBar background color
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0), // Padding around the content
        child: Form(
          key: _formKey, // Form key for validation
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center, // Center the content vertically
            children: <Widget>[
              Text(
                'Login',
                style: Theme.of(context).textTheme.headlineMedium, // Uses the headline style from the app theme
              ),
              SizedBox(height: 20), // Space between title and email field

              // Email field
              TextFormField(
                controller: emailController, // Connect the controller to the email input
                decoration: InputDecoration(
                  labelText: 'Email', // Placeholder text
                  border: OutlineInputBorder(borderSide: BorderSide(color: Colors.black)), // Border style
                  focusedBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.black)), // Focused border
                ),
                keyboardType: TextInputType.emailAddress, // Show email keyboard layout
                validator: (value) {
                  if (value == null || value.isEmpty) {
                    return 'Please enter your email'; // Error if the field is empty
                  }
                  if (!RegExp(r'^[^@]+@[^@]+\.[^@]+').hasMatch(value)) {
                    return 'Please enter a valid email'; // Error if the email format is invalid
                  }
                  return null; // No error if the field is valid
                },
              ),
              SizedBox(height: 10), // Space between email and password fields

              // Password field
              TextFormField(
                controller: passwordController, // Connect the controller to the password input
                obscureText: true, // Hides the input for passwords
                decoration: InputDecoration(
                  labelText: 'Password', // Placeholder text
                  border: OutlineInputBorder(borderSide: BorderSide(color: Colors.black)), // Border style
                  focusedBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.black)), // Focused border
                ),
                validator: (value) {
                  if (value == null || value.isEmpty) {
                    return 'Please enter your password'; // Error if the field is empty
                  }
                  return null; // No error if the field is valid
                },
              ),
              SizedBox(height: 20), // Space before the login button

              // Login button
              ElevatedButton(
                onPressed: () async {
                  // Validate the form before proceeding
                  if (_formKey.currentState!.validate()) {
                    try {
                      // Sign in the user with Firebase
                      UserCredential userCredential = await _auth.signInWithEmailAndPassword(
                        email: emailController.text.trim(),
                        password: passwordController.text.trim(),
                      );
                      // If successful, navigate to the Dashboard
                      Navigator.pushReplacementNamed(context, '/dashboard');
                    } on FirebaseAuthException catch (e) {
                      // Handle error during sign-in
                      String errorMessage;
                      if (e.code == 'user-not-found') {
                        errorMessage = 'No user found for that email.';
                      } else if (e.code == 'wrong-password') {
                        errorMessage = 'Wrong password provided for that user.';
                      } else {
                        errorMessage = 'An error occurred. Please try again.';
                      }
                      // Show error message
                      ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(errorMessage)));
                    }
                  }
                },
                style: ElevatedButton.styleFrom(
                  backgroundColor: Colors.teal, // Button background color
                  foregroundColor: Colors.white, // Button text color
                ),
                child: Text('Login'), // Button text
              ),
              SizedBox(height: 10), // Space before the register link

              // Register link
              TextButton(
                onPressed: () {
                  Navigator.pushNamed(context, '/register'); // Navigate to Register page
                },
                child: Text('Don\'t have an account? Register here'), // Register link text
                style: TextButton.styleFrom(
                  foregroundColor: Colors.teal, // Text color
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

Updated register.dart

Now, let’s update the RegisterPage to handle user registration:

import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart'; // Import Firebase Auth

// Defining the RegisterPage class
class RegisterPage extends StatefulWidget {
  @override
  _RegisterPageState createState() => _RegisterPageState();
}

class _RegisterPageState extends State<RegisterPage> {
  // Controllers for email and password fields
  final TextEditingController emailController = TextEditingController();
  final TextEditingController passwordController = TextEditingController();

  // Key to manage the form validation
  final _formKey = GlobalKey<FormState>();
  final FirebaseAuth _auth = FirebaseAuth.instance; // Firebase Auth instance

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Register to PocketWallet', style: TextStyle(color: Colors.white)), // AppBar title
        backgroundColor: Colors.teal, // AppBar background color
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0), // Padding around the content
        child: Form(
          key: _formKey, // Form key for validation
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center, // Center the content vertically
            children: <Widget>[
              Text(
                'Register',
                style: Theme.of(context).textTheme.headlineMedium, // Uses a predefined text style from the app's theme
              ),
              SizedBox(height: 20), // Space between title and email field

              // Email field
              TextFormField(
                controller: emailController, // Connect the controller to the email input
                decoration: InputDecoration(
                  labelText: 'Email', // Placeholder text
                  border: OutlineInputBorder(borderSide: BorderSide(color: Colors.black)), // Border style
                  focusedBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.black)), // Focused border
                ),
                keyboardType: TextInputType.emailAddress, // Show email keyboard layout
                validator: (value) {
                  if (value == null || value.isEmpty) {
                    return 'Please enter your email'; // Error if the field is empty
                  }
                  if (!RegExp(r'^[^@]+@[^@]+\.[^@]+').hasMatch(value)) {
                    return 'Please enter a valid email'; // Error if the email format is invalid
                  }
                  return null; // No error if the field is valid
                },
              ),
              SizedBox(height: 10), // Space between email and password fields

              // Password field
              TextFormField(
                controller: passwordController, // Connect the controller to the password input
                obscureText: true, // Hides the input for passwords
                decoration: InputDecoration(
                  labelText: 'Password', // Placeholder text
                  border: OutlineInputBorder(borderSide: BorderSide(color: Colors.black)), // Border style
                  focusedBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.black)), // Focused border
                ),
                validator: (value) {
                  if (value == null || value.isEmpty) {
                    return 'Please enter your password'; // Error if the field is empty
                  }
                  if (value.length < 6) {
                    return 'Password must be at least 6 characters long'; // Error if the password is too short
                  }
                  return null; // No error if the field is valid
                },
              ),
              SizedBox(height: 20), // Space before the register button

              // Register button
              ElevatedButton(
                onPressed: () async {
                  // Validate the form before proceeding
                  if (_formKey.currentState!.validate()) {
                    try {
                      // Create a new user with Firebase
                      UserCredential userCredential = await _auth.createUserWithEmailAndPassword(
                        email: emailController.text.trim(),
                        password: passwordController.text.trim(),
                      );
                      // If successful, navigate to the Dashboard
                      Navigator.pushReplacementNamed(context, '/dashboard');
                    } on FirebaseAuthException catch (e) {
                      // Handle error during registration
                      String errorMessage;
                      if (e.code == 'weak-password') {
                        errorMessage = 'The password provided is too weak.';
                      } else if (e.code == 'email-already-in-use') {
                        errorMessage = 'The account already exists for that email.';
                      } else {
                        errorMessage = 'An error occurred. Please try again.';
                      }
                      // Show error message
                      ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(errorMessage)));
                    }
                  }
                },
                style: ElevatedButton.styleFrom(
                  backgroundColor: Colors.teal, // Button background color
                  foregroundColor: Colors.white, // Button text color
                ),
                child: Text('Register'), // Button text
              ),
              SizedBox(height: 10), // Space before the login link

              // Login link
              TextButton(
                onPressed: () {
                  Navigator.pushNamed(context, '/'); // Navigate back to Login page
                },
                child: Text('Already have an account? Login here'), // Login link text
                style: TextButton.styleFrom(
                  foregroundColor: Colors.teal, // Text color
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

Final Notes

  1. Ensure Firebase Configuration: Make sure you correctly placed your google-se``rvices.json or GoogleService-Info.plist in the appropriate directory in your Flutter project.

  2. Permissions: For Android, ensure you have the necessary permissions in your AndroidManifest.xml.

  3. Testing: Run your app and test the login and registration functionality. Ensure that users can register and log in successfully.

  4. Error Handling: The above code includes basic error handling for common Firebase authentication errors.

More from this blog

React Js blog

23 posts