Paramclasses Academy - Blog

Tutorials Details

←
Post 29 of 39
→

How to Implement Email and Google Login with Firebase Authentication ?

How to Implement Email and Google Login with Firebase Authentication ?

November 5, 2026

1. Introduction

Authentication is an important feature of modern mobile applications. It allows users to create accounts, log in securely and access personalized information.

Firebase Authentication provides ready-to-use authentication services for mobile and web applications.

In this tutorial, we will implement two authentication methods in React Native:

  1. Email and Password Login.

  2. Google Sign-In.

Our practical project will be called Firebase Authentication App.

The application will include:

  • User Registration.

  • Email and Password Login.

  • Google Sign-In.

  • User Profile Screen.

  • Display User Name and Email.

  • Authentication State Management.

  • Logout Functionality.

  • Persistent Login Sessions.

2. What Is Firebase Authentication?

Firebase Authentication is a service provided by Google that allows developers to authenticate users without building a complete authentication backend from scratch.

It supports multiple authentication methods, including:

  • Email and Password.

  • Google Sign-In.

  • Phone Number Authentication.

  • Apple Sign-In.

  • Facebook Login.

  • Anonymous Authentication.

We will focus on Email/Password and Google authentication.

Official documentation:

https://firebase.google.com/docs/auth

3. Understanding Authentication Methods

3.1 Email and Password Authentication

In this method, users create an account using their email address and password.

Example:

Email: student@gmail.com
Password: ********

Firebase verifies the credentials and authenticates the user.

Important Firebase methods:

createUserWithEmailAndPassword()

Creates a new account.

signInWithEmailAndPassword()

Logs in an existing user.

signOut()

Logs out the current user.

3.2 Google Authentication

Google authentication allows users to sign in using an existing Google account.

Example workflow:

User
  |
  v
Sign in with Google
  |
  v
Google Account Selection
  |
  v
Google ID Token
  |
  v
Firebase Authentication
  |
  v
Authenticated User

The application receives a Google identity token and exchanges it for a Firebase authentication credential.

4. Understanding the Technology We Will Use

Our application will use:

Technology Purpose
React Native Mobile application development
Expo Development environment
Firebase Authentication backend
Firebase Auth User authentication
AsyncStorage Persistent authentication session
Google Sign-In SDK Google account selection

We will use Firebase JavaScript SDK for email authentication and Firebase credential authentication.

For native Google Sign-In, we will use @react-native-google-signin/google-signin.

Important: Email authentication can be tested using Expo Go. Native Google Sign-In requires a development build because the Google Sign-In package uses native code. It does not work inside Expo Go.

5. Create a Firebase Project

If you already created a Firebase project in Tutorial 29, you can use the same project.

Otherwise:

  1. Open https://console.firebase.google.com/

  2. Sign in with your Google account.

  3. Click Create a Project.

  4. Enter your project name.

  5. Complete the project creation process.

  6. Open your Firebase project.

6. Enable Email and Password Authentication

Now we need to enable Email/Password authentication.

Follow these steps:

  1. Open Firebase Console.

  2. Select your project.

  3. Navigate to Authentication.

  4. Open the Sign-in method tab.

  5. Select Email/Password.

  6. Enable Email/Password.

  7. Click Save.

Now Firebase allows users to register and log in using email and password.

Official documentation:

https://firebase.google.com/docs/auth/web/password-auth

7. Enable Google Authentication

Now enable Google authentication.

Follow these steps:

  1. Open Firebase Console.

  2. Navigate to Authentication.

  3. Open Sign-in method.

  4. Select Google.

  5. Enable the Google provider.

  6. Select a support email if required.

  7. Save the configuration.

Google authentication is now enabled in your Firebase project.

8. Register Your Android Application

For native Google Sign-In, your Android application must be registered correctly.

Open Firebase Console:

  1. Navigate to Project Settings.

  2. Open the General tab.

  3. Find Your Apps.

  4. Select Add App.

  5. Select Android.

  6. Enter your Android package name.

For example:

com.paramclasses.firebaseauth

Use your own unique package name.

Register the application.

Download google-services.json

After registering the Android application:

  1. Download google-services.json.

  2. Place the file in your Expo project's root directory.

Project example:

FirebaseAuthApp/
│
├── App.js
├── firebaseConfig.js
├── google-services.json
├── app.json
├── package.json
└── assets/

Configure SHA-1 Fingerprint

Google Sign-In requires the correct signing certificate configuration.

For Android development builds:

  1. Configure your EAS project.

  2. Generate or obtain the Android signing certificate.

  3. Find the SHA-1 fingerprint in your EAS credentials or Android signing configuration.

  4. Open Firebase Project Settings.

  5. Select your Android application.

  6. Add the SHA-1 fingerprint.

For production, also configure the Play App Signing certificate fingerprints.

You may need to add SHA-256 as well, depending on the Google authentication configuration.

After adding fingerprints, download the updated google-services.json.

9. Create a Web OAuth Client ID

Google Sign-In needs a Web OAuth Client ID to obtain the ID token used by Firebase.

Follow these steps:

  1. Open Google Cloud Console.

  2. Select the Google Cloud project associated with Firebase.

  3. Open Google Auth Platform or the OAuth credentials section.

  4. Configure the OAuth consent screen if requested.

  5. Create an OAuth 2.0 Client ID.

  6. Select Web application as the application type.

  7. Copy the generated Client ID.

It will look similar to:

123456789-example.apps.googleusercontent.com

Keep this Web Client ID available for the Google Sign-In configuration.

Do not use the Android Client ID in place of the Web Client ID.

10. Create a React Native Project

Open your terminal and execute:

npx create-expo-app@latest FirebaseAuthApp --template blank

Move into the project directory:

cd FirebaseAuthApp

Open the project:

code .

11. Install Required Packages

First install Firebase:

npx expo install firebase

Install AsyncStorage:

npx expo install @react-native-async-storage/async-storage

Install Google Sign-In:

npm install @react-native-google-signin/google-signin

These packages provide the functionality required for our application.

12. Configure app.json

Open app.json.

Configure the Android package name and Google Sign-In plugin.

Example:

{
  "expo": {
    "name": "FirebaseAuthApp",
    "slug": "firebase-auth-app",
    "version": "1.0.0",
    "android": {
      "package": "com.paramclasses.firebaseauth",
      "googleServicesFile": "./google-services.json"
    },
    "plugins": [
      "@react-native-google-signin/google-signin"
    ]
  }
}

Make sure the Android package name matches the application registered in Firebase.

If your project already contains other Expo configuration, preserve the existing required settings.

For iOS, register the iOS application separately and configure its GoogleService-Info.plist and Google OAuth URL scheme according to the official Expo guide.

13. Configure Firebase Authentication

Create a file named:

firebaseConfig.js

Add the following code:

import { initializeApp, getApp, getApps } from 'firebase/app';

import {
  initializeAuth,
  getReactNativePersistence
} from 'firebase/auth';

import AsyncStorage from '@react-native-async-storage/async-storage';

// Firebase configuration

const firebaseConfig = {
  apiKey: "YOUR_API_KEY",
  authDomain: "YOUR_PROJECT.firebaseapp.com",
  projectId: "YOUR_PROJECT_ID",
  storageBucket: "YOUR_STORAGE_BUCKET",
  messagingSenderId: "YOUR_SENDER_ID",
  appId: "YOUR_APP_ID"
};

// Initialize Firebase

const app = getApps().length
  ? getApp()
  : initializeApp(firebaseConfig);

// Initialize Firebase Authentication
// with persistent storage

const auth = initializeAuth(app, {
  persistence: getReactNativePersistence(AsyncStorage)
});

export { app, auth };

Replace the example values with the configuration from your Firebase Console.

Understanding the Code

initializeApp()

Initializes Firebase using the project configuration.

initializeAuth()

Initializes Firebase Authentication.

getReactNativePersistence()

Allows Firebase Authentication to maintain the user's login session using AsyncStorage.

AsyncStorage

Stores the authentication session information so that the user can remain signed in after closing and reopening the application.

Do not initialize Firebase Authentication again in another file. Import the existing auth instance wherever required.

14. Configure Google Sign-In

Open App.js and we will configure the Google Sign-In SDK.

Import:

import {
  GoogleSignin
} from '@react-native-google-signin/google-signin';

Configure the Web Client ID:

GoogleSignin.configure({
  webClientId: 'YOUR_WEB_CLIENT_ID.apps.googleusercontent.com',
});

Replace the placeholder with your actual Web OAuth Client ID.

This configuration connects the native Google Sign-In flow to the correct Google OAuth project.

15. Understand Important Firebase Authentication Methods

15.1 Create User Account

import {
  createUserWithEmailAndPassword
} from 'firebase/auth';

await createUserWithEmailAndPassword(
  auth,
  email,
  password
);

This creates a new Firebase user account.

15.2 Email Login

import {
  signInWithEmailAndPassword
} from 'firebase/auth';

await signInWithEmailAndPassword(
  auth,
  email,
  password
);

This authenticates an existing user.

15.3 Google Login

import {
  GoogleAuthProvider,
  signInWithCredential
} from 'firebase/auth';

const credential =
  GoogleAuthProvider.credential(idToken);

await signInWithCredential(
  auth,
  credential
);

This exchanges the Google ID token for a Firebase authentication session.

15.4 Logout

import {
  signOut
} from 'firebase/auth';

await signOut(auth);

This signs the user out of Firebase.

16. Build the Complete Authentication Application

Now we will create the complete application.

Our app will contain:

  • Login Screen.

  • Registration Screen.

  • Google Login Button.

  • User Dashboard.

  • User Information.

  • Logout Button.

Complete App.js Code

Open App.js and replace its existing code with the following:

import React, {
  useState,
  useEffect
} from 'react';

import {
  View,
  Text,
  TextInput,
  TouchableOpacity,
  StyleSheet,
  Alert,
  ActivityIndicator,
  ScrollView
} from 'react-native';

import {
  createUserWithEmailAndPassword,
  signInWithEmailAndPassword,
  GoogleAuthProvider,
  signInWithCredential,
  signOut,
  onAuthStateChanged
} from 'firebase/auth';

import {
  GoogleSignin
} from '@react-native-google-signin/google-signin';

import { auth } from './firebaseConfig';

// Google Sign-In Configuration

GoogleSignin.configure({
  webClientId: 'YOUR_WEB_CLIENT_ID.apps.googleusercontent.com',
});

export default function App() {

  const [isRegister, setIsRegister] =
    useState(false);

  const [email, setEmail] =
    useState('');

  const [password, setPassword] =
    useState('');

  const [confirmPassword, setConfirmPassword] =
    useState('');

  const [user, setUser] =
    useState(null);

  const [loading, setLoading] =
    useState(false);

  // Authentication state listener

  useEffect(() => {

    const unsubscribe = onAuthStateChanged(
      auth,
      (currentUser) => {

        setUser(currentUser);

      }
    );

    return unsubscribe;

  }, []);

  // Email Registration

  const registerUser = async () => {

    if (
      !email.trim() ||
      !password ||
      !confirmPassword
    ) {

      Alert.alert(
        'Validation',
        'Please fill in all fields.'
      );

      return;

    }

    if (
      !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(
        email.trim()
      )
    ) {

      Alert.alert(
        'Invalid Email',
        'Please enter a valid email.'
      );

      return;

    }

    if (password.length < 6) {

      Alert.alert(
        'Weak Password',
        'Password must contain at least 6 characters.'
      );

      return;

    }

    if (password !== confirmPassword) {

      Alert.alert(
        'Password Error',
        'Passwords do not match.'
      );

      return;

    }

    try {

      setLoading(true);

      await createUserWithEmailAndPassword(
        auth,
        email.trim(),
        password
      );

      Alert.alert(
        'Success',
        'Account created successfully.'
      );

      setPassword('');
      setConfirmPassword('');

    } catch (error) {

      console.log(
        'Registration Error:',
        error
      );

      Alert.alert(
        'Registration Failed',
        getAuthErrorMessage(error.code)
      );

    } finally {

      setLoading(false);

    }

  };

  // Email Login

  const loginUser = async () => {

    if (!email.trim() || !password) {

      Alert.alert(
        'Validation',
        'Please enter email and password.'
      );

      return;

    }

    try {

      setLoading(true);

      await signInWithEmailAndPassword(
        auth,
        email.trim(),
        password
      );

      Alert.alert(
        'Success',
        'Login successful.'
      );

    } catch (error) {

      console.log(
        'Login Error:',
        error
      );

      Alert.alert(
        'Login Failed',
        getAuthErrorMessage(error.code)
      );

    } finally {

      setLoading(false);

    }

  };

  // Google Login

  const googleLogin = async () => {

    try {

      setLoading(true);

      // Check Google Play Services

      await GoogleSignin.hasPlayServices({
        showPlayServicesUpdateDialog: true
      });

      // Open Google Account Selection

      const response =
        await GoogleSignin.signIn();

      // Extract Google ID Token

      const idToken =
        response.data?.idToken ??
        response.idToken;

      if (!idToken) {

        throw new Error(
          'Google ID token was not returned.'
        );

      }

      // Create Firebase Credential

      const googleCredential =
        GoogleAuthProvider.credential(idToken);

      // Sign in to Firebase

      await signInWithCredential(
        auth,
        googleCredential
      );

      Alert.alert(
        'Success',
        'Google login successful.'
      );

    } catch (error) {

      console.log(
        'Google Login Error:',
        error
      );

      if (
        error.code === 'SIGN_IN_CANCELLED'
      ) {

        return;

      }

      Alert.alert(
        'Google Login Failed',
        error.message || 'Unable to sign in with Google.'
      );

    } finally {

      setLoading(false);

    }

  };

  // Logout

  const logoutUser = async () => {

    try {

      setLoading(true);

      // Sign out from Firebase

      await signOut(auth);

      // Sign out from Google account session

      try {

        await GoogleSignin.signOut();

      } catch (googleError) {

        console.log(
          'Google Sign-Out:',
          googleError
        );

      }

      Alert.alert(
        'Success',
        'You have been logged out.'
      );

    } catch (error) {

      Alert.alert(
        'Logout Error',
        error.message
      );

    } finally {

      setLoading(false);

    }

  };

  // Firebase error messages

  const getAuthErrorMessage = (code) => {

    switch (code) {

      case 'auth/email-already-in-use':
        return 'This email is already registered.';

      case 'auth/invalid-email':
        return 'Invalid email address.';

      case 'auth/weak-password':
        return 'Please choose a stronger password.';

      case 'auth/invalid-credential':
        return 'Invalid email or password.';

      case 'auth/user-disabled':
        return 'This account has been disabled.';

      case 'auth/network-request-failed':
        return 'Please check your internet connection.';

      case 'auth/operation-not-allowed':
        return 'This authentication method is not enabled.';

      default:
        return 'Something went wrong. Please try again.';

    }

  };

  // Dashboard Screen

  if (user) {

    return (

      <View style={styles.container}>

        <View style={styles.dashboard}>

          <Text style={styles.welcome}>
            Welcome!
          </Text>

          <Text style={styles.dashboardTitle}>
            Firebase Dashboard
          </Text>

          <View style={styles.profileCircle}>

            <Text style={styles.profileText}>
              {(
                user.displayName ||
                user.email ||
                'U'
              ).charAt(0).toUpperCase()}
            </Text>

          </View>

          <Text style={styles.userName}>
            {user.displayName || 'Student User'}
          </Text>

          <Text style={styles.userEmail}>
            {user.email || 'No email available'}
          </Text>

          <View style={styles.infoCard}>

            <Text style={styles.infoLabel}>
              User ID
            </Text>

            <Text style={styles.infoValue}>
              {user.uid}
            </Text>

            <Text style={styles.infoLabel}>
              Authentication Provider
            </Text>

            <Text style={styles.infoValue}>
              {user.providerData
                .map((item) => item.providerId)
                .join(', ')}
            </Text>

            <Text style={styles.infoLabel}>
              Email Verified
            </Text>

            <Text style={styles.infoValue}>
              {user.emailVerified ? 'Yes' : 'Not verified'}
            </Text>

          </View>

          <TouchableOpacity
            style={styles.logoutButton}
            onPress={logoutUser}
            disabled={loading}
          >

            <Text style={styles.buttonText}>
              Logout
            </Text>

          </TouchableOpacity>

        </View>

        {loading && (
          <ActivityIndicator
            size="large"
            color="#2563eb"
          />
        )}

      </View>

    );

  }

  // Login and Registration Screen

  return (

    <ScrollView
      contentContainerStyle={styles.scrollContainer}
    >

      <View style={styles.container}>

        <Text style={styles.title}>
          PARAM CLASSES
        </Text>

        <Text style={styles.subtitle}>
          Firebase Authentication App
        </Text>

        <View style={styles.card}>

          <Text style={styles.heading}>
            {isRegister
              ? 'Create Account'
              : 'Welcome Back'}
          </Text>

          <Text style={styles.description}>
            {isRegister
              ? 'Register using your email address.'
              : 'Login to continue to your account.'}
          </Text>

          <TextInput
            style={styles.input}
            placeholder="Enter Email Address"
            value={email}
            onChangeText={setEmail}
            keyboardType="email-address"
            autoCapitalize="none"
            autoCorrect={false}
          />

          <TextInput
            style={styles.input}
            placeholder="Enter Password"
            value={password}
            onChangeText={setPassword}
            secureTextEntry
          />

          {isRegister && (

            <TextInput
              style={styles.input}
              placeholder="Confirm Password"
              value={confirmPassword}
              onChangeText={setConfirmPassword}
              secureTextEntry
            />

          )}

          <TouchableOpacity
            style={styles.primaryButton}
            onPress={
              isRegister
                ? registerUser
                : loginUser
            }
            disabled={loading}
          >

            <Text style={styles.buttonText}>
              {isRegister
                ? 'Register'
                : 'Login'}
            </Text>

          </TouchableOpacity>

          <View style={styles.dividerRow}>

            <View style={styles.line} />

            <Text style={styles.orText}>
              OR
            </Text>

            <View style={styles.line} />

          </View>

          <TouchableOpacity
            style={styles.googleButton}
            onPress={googleLogin}
            disabled={loading}
          >

            <Text style={styles.googleButtonText}>
              G
            </Text>

            <Text style={styles.googleText}>
              Continue with Google
            </Text>

          </TouchableOpacity>

          <TouchableOpacity
            onPress={() => {

              setIsRegister(!isRegister);

              setPassword('');

              setConfirmPassword('');

            }}
          >

            <Text style={styles.switchText}>
              {isRegister
                ? 'Already have an account? Login'
                : "Don't have an account? Register"}
            </Text>

          </TouchableOpacity>

        </View>

        {loading && (

          <ActivityIndicator
            size="large"
            color="#2563eb"
            style={styles.loader}
          />

        )}

      </View>

    </ScrollView>

  );

}

const styles = StyleSheet.create({

  scrollContainer: {
    flexGrow: 1,
  },

  container: {
    flex: 1,
    backgroundColor: '#eff6ff',
    justifyContent: 'center',
    padding: 22,
  },

  title: {
    fontSize: 27,
    fontWeight: 'bold',
    color: '#1d4ed8',
    textAlign: 'center',
  },

  subtitle: {
    fontSize: 14,
    color: '#64748b',
    textAlign: 'center',
    marginTop: 8,
    marginBottom: 25,
  },

  card: {
    backgroundColor: '#ffffff',
    padding: 22,
    borderRadius: 18,
    elevation: 4,
  },

  heading: {
    fontSize: 24,
    fontWeight: 'bold',
    color: '#0f172a',
  },

  description: {
    fontSize: 13,
    color: '#64748b',
    marginTop: 7,
    marginBottom: 22,
  },

  input: {
    borderWidth: 1,
    borderColor: '#cbd5e1',
    backgroundColor: '#f8fafc',
    padding: 14,
    borderRadius: 10,
    marginBottom: 15,
    fontSize: 15,
  },

  primaryButton: {
    backgroundColor: '#2563eb',
    padding: 15,
    borderRadius: 10,
    alignItems: 'center',
  },

  buttonText: {
    color: '#ffffff',
    fontWeight: 'bold',
    fontSize: 16,
  },

  dividerRow: {
    flexDirection: 'row',
    alignItems: 'center',
    marginVertical: 22,
  },

  line: {
    flex: 1,
    height: 1,
    backgroundColor: '#cbd5e1',
  },

  orText: {
    marginHorizontal: 12,
    color: '#64748b',
  },

  googleButton: {
    borderWidth: 1,
    borderColor: '#cbd5e1',
    borderRadius: 10,
    padding: 13,
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
  },

  googleButtonText: {
    color: '#4285F4',
    fontSize: 21,
    fontWeight: 'bold',
    marginRight: 12,
  },

  googleText: {
    color: '#1e293b',
    fontSize: 15,
    fontWeight: '600',
  },

  switchText: {
    textAlign: 'center',
    color: '#2563eb',
    marginTop: 22,
    fontWeight: '600',
  },

  loader: {
    marginTop: 20,
  },

  dashboard: {
    backgroundColor: '#ffffff',
    padding: 22,
    borderRadius: 18,
    elevation: 4,
    alignItems: 'center',
  },

  welcome: {
    fontSize: 16,
    color: '#64748b',
  },

  dashboardTitle: {
    fontSize: 23,
    fontWeight: 'bold',
    color: '#1d4ed8',
    marginTop: 8,
  },

  profileCircle: {
    width: 85,
    height: 85,
    borderRadius: 43,
    backgroundColor: '#dbeafe',
    alignItems: 'center',
    justifyContent: 'center',
    marginVertical: 22,
  },

  profileText: {
    fontSize: 34,
    fontWeight: 'bold',
    color: '#2563eb',
  },

  userName: {
    fontSize: 21,
    fontWeight: 'bold',
    color: '#0f172a',
  },

  userEmail: {
    fontSize: 14,
    color: '#64748b',
    marginTop: 7,
  },

  infoCard: {
    width: '100%',
    backgroundColor: '#f8fafc',
    padding: 15,
    borderRadius: 12,
    marginTop: 25,
  },

  infoLabel: {
    color: '#64748b',
    fontSize: 12,
    marginTop: 10,
  },

  infoValue: {
    color: '#1e293b',
    fontSize: 13,
    fontWeight: '600',
    marginTop: 5,
  },

  logoutButton: {
    backgroundColor: '#dc2626',
    padding: 15,
    width: '100%',
    alignItems: 'center',
    borderRadius: 10,
    marginTop: 25,
  },

});

Important implementation notes:

  • The example uses the original GoogleSignin API. Its response handling checks both response.data.idToken and response.idToken to accommodate the response shapes used by different package releases. Verify the installed package's API if your version differs.

  • The code uses a custom Google button. It starts the native Google account selection flow.

  • The dashboard displays the authenticated Firebase user's information.

  • Firebase Authentication state is observed using onAuthStateChanged().

17. Understand the Registration Workflow

When a user selects Register, the registerUser() function executes.

First, the application checks whether all fields are filled.

Then it checks:

  • Email format.

  • Password length.

  • Password confirmation.

After validation, it executes:

await createUserWithEmailAndPassword(
  auth,
  email.trim(),
  password
);

Firebase creates the account and automatically signs the new user in.

The authentication listener detects the new user and displays the dashboard.

18. Understand the Login Workflow

When an existing user enters their credentials and presses Login, this function executes:

await signInWithEmailAndPassword(
  auth,
  email.trim(),
  password
);

Firebase checks the credentials.

If the credentials are correct, Firebase authenticates the user.

If the credentials are incorrect, an error is returned.

19. Understand the Google Login Workflow

Google login follows these steps:

Step 1: Check Google Play Services

await GoogleSignin.hasPlayServices({
  showPlayServicesUpdateDialog: true
});

This checks the availability of Google Play Services on Android.

Step 2: Open Google Sign-In

const response =
  await GoogleSignin.signIn();

The Google account selection interface appears.

Step 3: Get Google ID Token

const idToken =
  response.data?.idToken ??
  response.idToken;

The application extracts the ID token from the successful response.

Step 4: Create Firebase Credential

const googleCredential =
  GoogleAuthProvider.credential(idToken);

Firebase converts the Google ID token into a Google authentication credential.

Step 5: Authenticate with Firebase

await signInWithCredential(
  auth,
  googleCredential
);

Firebase authenticates the user and creates a Firebase session.

20. Understand Authentication State Management

One of the most important concepts in this application is:

onAuthStateChanged()

This listener detects whether a user is logged in or logged out.

Example:

useEffect(() => {

  const unsubscribe = onAuthStateChanged(
    auth,
    (currentUser) => {

      setUser(currentUser);

    }
  );

  return unsubscribe;

}, []);

When a user logs in:

currentUser !== null

When a user logs out:

currentUser === null

We use this state to decide which screen should be displayed.

21. Configure an Expo Development Build

The Email/Password functionality can run in Expo Go.

However, the native Google Sign-In package cannot run in Expo Go.

For Google Sign-In, configure an Expo development build.

First, install EAS CLI if required:

npm install -g eas-cli

Log in:

eas login

Configure the project:

eas build:configure

Create a development build for Android:

eas build --profile development --platform android

Install the generated development build on your Android device or emulator.

If you are building locally with Android Studio, you can also use:

npx expo prebuild

Then:

npx expo run:android

If you modify native configuration or add a native package, rebuild the development application.

Official Expo Google Authentication guide:

https://docs.expo.dev/guides/google-authentication/

22. Test Email Registration

Open the application.

Enter:

Email: student@gmail.com
Password: student123
Confirm Password: student123

Press Register.

Expected result:

  • Firebase creates a new user.

  • The user becomes authenticated.

  • The dashboard appears.

  • The user information is displayed.

Use a real email address if you plan to test email verification later.

23. Test Email Login

First, log out.

Return to the login screen.

Enter the registered email and password.

Press Login.

Expected result:

The user should successfully enter the dashboard.

24. Test Google Sign-In

Run the development build.

Press:

Continue with Google

Then:

  1. Select a Google account.

  2. Complete the Google authentication flow.

  3. Wait for Firebase to verify the Google credential.

  4. Check the application dashboard.

Expected result:

The Google user's account information should appear in the dashboard.

Open Firebase Console and navigate to:

Authentication → Users

You should see the authenticated user in the Firebase user list.

25. Test Logout Functionality

On the dashboard, press Logout.

The application executes:

await signOut(auth);

It also signs out the Google Sign-In SDK session.

Expected result:

  • Firebase session ends.

  • User state becomes null.

  • Login screen appears again.

26. Test Persistent Login

Our application uses:

getReactNativePersistence(AsyncStorage)

This allows Firebase Authentication to restore the session after an application restart.

Testing procedure:

  1. Register or log in.

  2. Close the application completely.

  3. Open the application again.

  4. Wait for Firebase to restore the authentication state.

Expected result:

The user should remain logged in unless they have signed out or their session has otherwise become invalid.

27. Common Errors and Solutions

Error 1: Operation Not Allowed

Example:

auth/operation-not-allowed

Reason: The Email/Password provider is disabled.

Solution:

Open Firebase Console → Authentication → Sign-in method.

Enable Email/Password.

Error 2: Email Already Exists

Example:

auth/email-already-in-use

Reason: An account already exists with the supplied email address.

Solution:

Use another email address or log in using the existing account.

Error 3: Invalid Credential

Example:

auth/invalid-credential

Reason: The email or password is incorrect, or the supplied credential is invalid.

Solution:

Verify the credentials and authentication configuration.

Error 4: Google Sign-In Not Working in Expo Go

Reason: The native Google Sign-In package requires custom native code.

Solution:

Create and install an Expo development build.

Error 5: Developer Error Code 10

Possible reasons:

  • Incorrect Android package name.

  • Missing SHA-1 fingerprint.

  • Incorrect Web Client ID.

  • Outdated google-services.json.

  • Incorrect signing certificate.

Solution:

Verify the package name and certificate fingerprints in Firebase Console.

Download the updated configuration file and rebuild the Android application.

Error 6: Google ID Token Is Null

Possible reasons:

  • Incorrect OAuth configuration.

  • Wrong Web Client ID.

  • Google Sign-In configuration is incomplete.

  • Incorrect native Firebase configuration.

Solution:

Verify the Web OAuth Client ID and Firebase project settings.

Error 7: User Logs Out After Restarting the App

Reason: Firebase Authentication may be using memory-only persistence.

Solution:

Initialize Firebase Auth with getReactNativePersistence(AsyncStorage) as demonstrated in this tutorial.

28. Authentication Security Best Practices

Authentication should be implemented with appropriate security controls.

Follow these practices:

  1. Never store passwords in plain text.

  2. Never hardcode private service-account credentials in the application.

  3. Use Firebase Authentication rather than implementing your own password storage.

  4. Validate user input before submitting authentication requests.

  5. Enable email verification when your application requires verified email addresses.

  6. Use secure session handling.

  7. Apply Firebase Security Rules to protect Firestore and Storage resources.

  8. Use HTTPS for communication with your backend.

  9. Never trust client-side authentication checks as the only protection for backend data.

  10. Restrict sensitive resources using authenticated user identity and authorization rules.

Remember: Firebase Authentication identifies the user, while Firebase Security Rules control what the user can access.

29. Practical Exercises

Complete the following exercises to improve your authentication skills.

Exercise 1: Add a Forgot Password feature using Firebase sendPasswordResetEmail().

Exercise 2: Add an email verification feature using sendEmailVerification().

Exercise 3: Add a Show Password button.

Exercise 4: Display the user's Google profile photo if available.

Exercise 5: Add a separate profile screen.

Exercise 6: Add an account deletion feature using Firebase Authentication.

Exercise 7: Add a protected Firestore collection where each user can access only their own records.

30. Frequently Asked Questions

Q1. What is Firebase Authentication?

Firebase Authentication is a service that allows developers to authenticate users using email, password, Google and other supported providers.

Q2. Can we use Firebase Authentication in React Native?

Yes. Firebase Authentication can be integrated into React Native applications using Firebase SDKs.

Q3. Can Email/Password Login work in Expo Go?

Yes. The Firebase JavaScript SDK supports Email/Password authentication in Expo Go.

Q4. Can native Google Sign-In work in Expo Go?

No. The native Google Sign-In package requires a development build.

Q5. What is a Google ID Token?

A Google ID token is a signed identity token that provides information about an authenticated Google account.

Q6. What is the difference between Google Login and Firebase Login?

Google Login authenticates a user through Google. Firebase Login creates an authenticated session in your Firebase project using the Google credential.

Q7. What is AsyncStorage used for?

AsyncStorage provides persistent local key-value storage. In this project, Firebase Auth uses it to maintain the user's authentication session.

Q8. Can a user log in with both email and Google?

Yes. Firebase supports multiple authentication providers. Account linking can be implemented when the same person needs to use multiple providers with one Firebase account.

31. Conclusion

In this tutorial, we learned how to implement Email and Google authentication in React Native using Firebase.

We covered:

  • Creating a Firebase project.

  • Enabling Email/Password authentication.

  • Enabling Google authentication.

  • Registering an Android application.

  • Configuring SHA-1 fingerprints.

  • Creating a Google OAuth Client ID.

  • Installing Firebase Authentication packages.

  • Implementing user registration.

  • Implementing email login.

  • Implementing Google Sign-In.

  • Managing authentication state.

  • Implementing logout.

  • Maintaining persistent login sessions.

  • Testing authentication.

  • Understanding authentication security.

Finally, we created a complete Firebase Authentication App with registration, login, Google Sign-In and a user dashboard.

Firebase Authentication is an important foundation for building secure mobile applications with personalized user accounts.

←
Post 29 of 39
→