6-deploying-a-flutter-app-with-firebase-authentication-and-firestore.html

Deploying a Flutter App with Firebase Authentication and Firestore

Flutter, Google's UI toolkit for building natively compiled applications for mobile, web, and desktop from a single codebase, has gained immense popularity among developers. One of the key features that many apps require is user authentication and real-time data storage. Firebase, a Backend-as-a-Service (BaaS) platform, provides robust solutions for these needs. In this article, we'll explore how to deploy a Flutter app using Firebase authentication and Firestore, the cloud-hosted NoSQL database.

Why Use Firebase with Flutter?

Firebase offers several advantages for Flutter developers:

  • Real-time Data Sync: Firestore allows you to sync data in real-time across clients.
  • Scalability: Firebase can handle applications with large user bases.
  • Ease of Use: Firebase provides a straightforward API and excellent documentation.
  • Authentication: Firebase Authentication supports multiple sign-in methods, including email/password, Google, Facebook, and more.

Prerequisites

Before we dive into the code, you should have:

  • Flutter installed on your machine.
  • A Firebase project set up in the Firebase Console.
  • The FlutterFire plugin installed. You can do this by adding dependencies to your pubspec.yaml.
dependencies:
  flutter:
    sdk: flutter
  firebase_core: latest_version
  firebase_auth: latest_version
  cloud_firestore: latest_version

Step 1: Setting Up Firebase

  1. Create a Firebase Project: Go to the Firebase Console and create a new project.
  2. Add an App: Click on "Add App" and select your platform (iOS or Android).
  3. Register App: Follow the instructions to register your app, download the google-services.json (for Android) or GoogleService-Info.plist (for iOS), and place it in the appropriate directory.

Step 2: Initialize Firebase in Your Flutter App

Open your main.dart file and initialize Firebase in the main function. Ensure you have the necessary imports:

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

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Firebase Auth',
      home: HomeScreen(),
    );
  }
}

Step 3: Implementing Firebase Authentication

Email/Password Authentication

Create a new file called auth_service.dart to handle authentication:

import 'package:firebase_auth/firebase_auth.dart';

class AuthService {
  final FirebaseAuth _auth = FirebaseAuth.instance;

  Future<User?> signInWithEmail(String email, String password) async {
    try {
      UserCredential userCredential = await _auth.signInWithEmailAndPassword(email: email, password: password);
      return userCredential.user;
    } catch (e) {
      print(e);
      return null;
    }
  }

  Future<User?> registerWithEmail(String email, String password) async {
    try {
      UserCredential userCredential = await _auth.createUserWithEmailAndPassword(email: email, password: password);
      return userCredential.user;
    } catch (e) {
      print(e);
      return null;
    }
  }

  Future<void> signOut() async {
    await _auth.signOut();
  }
}

User Interface for Authentication

In your home_screen.dart, create a simple login and registration form:

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

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  final AuthService _authService = AuthService();
  final TextEditingController _emailController = TextEditingController();
  final TextEditingController _passwordController = TextEditingController();

  void _login() async {
    User? user = await _authService.signInWithEmail(_emailController.text, _passwordController.text);
    if (user != null) {
      // Navigate to the next screen
    }
  }

  void _register() async {
    User? user = await _authService.registerWithEmail(_emailController.text, _passwordController.text);
    if (user != null) {
      // Navigate to the next screen
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Firebase Auth')),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: [
            TextField(controller: _emailController, decoration: InputDecoration(labelText: 'Email')),
            TextField(controller: _passwordController, decoration: InputDecoration(labelText: 'Password'), obscureText: true),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                ElevatedButton(onPressed: _login, child: Text('Login')),
                ElevatedButton(onPressed: _register, child: Text('Register')),
              ],
            )
          ],
        ),
      ),
    );
  }
}

Step 4: Using Firestore for Data Storage

Writing Data to Firestore

Create a new file called firestore_service.dart:

import 'package:cloud_firestore/cloud_firestore.dart';

class FirestoreService {
  final FirebaseFirestore _db = FirebaseFirestore.instance;

  Future<void> addUserData(String uid, String email) {
    return _db.collection('users').doc(uid).set({
      'email': email,
      'createdAt': Timestamp.now(),
    });
  }
}

Saving User Data on Registration

Modify the _register function in home_screen.dart to save user data:

void _register() async {
    User? user = await _authService.registerWithEmail(_emailController.text, _passwordController.text);
    if (user != null) {
      FirestoreService().addUserData(user.uid, user.email!);
      // Navigate to the next screen
    }
}

Troubleshooting Common Issues

  • Firebase Initialization Error: Ensure you have followed all the steps to set up your Firebase project and that your google-services.json or GoogleService-Info.plist files are in the correct location.
  • Permissions Issues: If you encounter permission denied errors, check your Firestore rules in the Firebase Console.
  • Network Issues: Make sure your device/emulator has internet access.

Conclusion

Deploying a Flutter app with Firebase authentication and Firestore is a powerful way to create scalable applications with real-time data capabilities. Through this guide, you’ve learned how to set up Firebase, implement user authentication, and store user data in Firestore. With these foundations, you're well on your way to building robust applications that leverage the strengths of both Flutter and Firebase. Happy coding!

SR
Syed
Rizwan

About the Author

Syed Rizwan is a Machine Learning Engineer with 5 years of experience in AI, IoT, and Industrial Automation.