0
0
Fluttermobile~20 mins

Firebase Authentication in Flutter - Mini App: Build & Ship

Choose your learning style9 modes available
Build: Login Screen
This screen allows users to sign in using their email and password with Firebase Authentication.
Target UI
┌───────────────────────────────┐
│           Login Screen         │
├───────────────────────────────┤
│ Email: ______________________ │
│ Password: ___________________ │
│                               │
│ [ Sign In ]                   │
│                               │
│ Don't have an account? Sign Up│
└───────────────────────────────┘
Two TextFields: one for email, one for password
A Sign In button that authenticates with Firebase
Show a loading indicator while signing in
Show error message if sign in fails
A text button to navigate to a Sign Up screen (navigation logic can be a placeholder)
Starter Code
Flutter
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';

class LoginScreen extends StatefulWidget {
  @override
  State<LoginScreen> createState() => _LoginScreenState();
}

class _LoginScreenState extends State<LoginScreen> {
  final TextEditingController emailController = TextEditingController();
  final TextEditingController passwordController = TextEditingController();
  bool isLoading = false;
  String? errorMessage;

  void signIn() async {
    // TODO: Implement Firebase sign in logic here
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Login Screen')),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            TextField(
              controller: emailController,
              decoration: InputDecoration(labelText: 'Email'),
              keyboardType: TextInputType.emailAddress,
            ),
            SizedBox(height: 12),
            TextField(
              controller: passwordController,
              decoration: InputDecoration(labelText: 'Password'),
              obscureText: true,
            ),
            SizedBox(height: 24),
            if (errorMessage != null) ...[
              Text(errorMessage!, style: TextStyle(color: Colors.red)),
              SizedBox(height: 12),
            ],
            isLoading
                ? CircularProgressIndicator()
                : ElevatedButton(
                    onPressed: signIn,
                    child: Text('Sign In'),
                  ),
            SizedBox(height: 24),
            TextButton(
              onPressed: () {
                // TODO: Navigate to Sign Up screen
              },
              child: Text("Don't have an account? Sign Up"),
            ),
          ],
        ),
      ),
    );
  }
}
Task 1
Task 2
Task 3
Task 4
Solution
Flutter
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';

class LoginScreen extends StatefulWidget {
  @override
  State<LoginScreen> createState() => _LoginScreenState();
}

class _LoginScreenState extends State<LoginScreen> {
  final TextEditingController emailController = TextEditingController();
  final TextEditingController passwordController = TextEditingController();
  bool isLoading = false;
  String? errorMessage;

  void signIn() async {
    setState(() {
      isLoading = true;
      errorMessage = null;
    });
    try {
      await FirebaseAuth.instance.signInWithEmailAndPassword(
        email: emailController.text.trim(),
        password: passwordController.text.trim(),
      );
      // On success, you might navigate to another screen
      // For this example, just clear inputs
      emailController.clear();
      passwordController.clear();
    } on FirebaseAuthException catch (e) {
      setState(() {
        errorMessage = e.message ?? 'Sign in failed';
      });
    } catch (_) {
      setState(() {
        errorMessage = 'An unexpected error occurred';
      });
    } finally {
      setState(() {
        isLoading = false;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Login Screen')),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            TextField(
              controller: emailController,
              decoration: InputDecoration(labelText: 'Email'),
              keyboardType: TextInputType.emailAddress,
            ),
            SizedBox(height: 12),
            TextField(
              controller: passwordController,
              decoration: InputDecoration(labelText: 'Password'),
              obscureText: true,
            ),
            SizedBox(height: 24),
            if (errorMessage != null) ...[
              Text(errorMessage!, style: TextStyle(color: Colors.red)),
              SizedBox(height: 12),
            ],
            isLoading
                ? CircularProgressIndicator()
                : ElevatedButton(
                    onPressed: signIn,
                    child: Text('Sign In'),
                  ),
            SizedBox(height: 24),
            TextButton(
              onPressed: () {
                // Placeholder for navigation to Sign Up screen
              },
              child: Text("Don't have an account? Sign Up"),
            ),
          ],
        ),
      ),
    );
  }
}

This solution uses FirebaseAuth's signInWithEmailAndPassword method to authenticate users with their email and password.

We show a loading spinner while waiting for the sign-in process to complete.

If an error occurs, we catch it and display the error message below the input fields in red.

The Sign Up button currently has a placeholder for navigation logic, which you can implement later.

This approach keeps the UI responsive and informs the user about the sign-in status clearly.

Final Result
Completed Screen
┌───────────────────────────────┐
│           Login Screen         │
├───────────────────────────────┤
│ Email: user@example.com       │
│ Password: ********            │
│                               │
│ [ Sign In ]                   │
│                               │
│ Don't have an account? Sign Up│
└───────────────────────────────┘
User enters email and password in text fields
Taps 'Sign In' button to start authentication
Loading spinner appears while signing in
If sign in fails, error message appears in red below inputs
Tapping 'Don't have an account? Sign Up' triggers navigation placeholder
Stretch Goal
Add a 'Forgot Password?' button that sends a password reset email using Firebase Authentication.
💡 Hint
Use FirebaseAuth.instance.sendPasswordResetEmail(email: userEmail) and show a confirmation message.