What is Firebase?

Firebase is Google's Backend-as-a-Service (BaaS) platform that provides everything you need to build a mobile app without writing backend code. Think of it like a restaurant kitchen that's already fully equipped - you don't need to buy ovens, hire chefs, or manage inventory. You just focus on creating great dishes (your app features).

Instead of spending months building servers, databases, and APIs, Firebase gives you production-ready backend services that work out of the box. It's like having a team of backend engineers working for you 24/7.

Why Use Firebase?

  • Zero Backend Code: No need to write server-side code or manage servers
  • Real-time Updates: Data syncs instantly across all devices
  • Scales Automatically: Handles 10 users or 10 million users seamlessly
  • Free to Start: Generous free tier, pay only as you grow
  • Fast Development: Build MVPs in days, not months
  • Google Infrastructure: Same reliability as Gmail and YouTube
  • Comprehensive: Auth, database, storage, hosting - all in one
  • Great Documentation: Easy to learn with tons of examples

When to Use Firebase (BaaS)?

Perfect For:

  • Startups building MVPs quickly
  • Apps needing real-time features (chat, collaboration)
  • Small teams without backend developers
  • Apps with user authentication and data storage
  • Prototypes and proof-of-concepts
  • Apps that need to scale unpredictably

Consider Custom Backend When:

  • Complex business logic requiring custom algorithms
  • Need full control over infrastructure
  • Handling sensitive data with strict compliance (healthcare, finance)
  • Very high transaction volumes with complex queries
  • Need to integrate with legacy systems extensively

Core Firebase Services

Firebase Services Overview:
┌────────────────────────────────────┐
│ Authentication                     │  User login/signup
│ Firestore Database                 │  NoSQL cloud database
│ Realtime Database                  │  Real-time data sync
│ Cloud Storage                      │  File uploads (images, videos)
│ Cloud Functions                    │  Serverless backend code
│ Hosting                            │  Web app hosting
│ Cloud Messaging (FCM)              │  Push notifications
│ Analytics                          │  User behavior tracking
│ Crashlytics                        │  Crash reporting
└────────────────────────────────────┘

Firebase Authentication

Authentication is how users sign up and log in to your app. Firebase handles all the complexity - password hashing, email verification, social login, and more. Think of it as a bouncer at a club who checks IDs and remembers who's allowed in.

Supported Sign-In Methods

  • Email/Password: Traditional login
  • Google: Sign in with Google account
  • Facebook, Twitter, GitHub: Social login
  • Phone Number: SMS verification
  • Anonymous: Temporary accounts
// Install Firebase
npm install @react-native-firebase/app @react-native-firebase/auth

// React Native Example
import auth from '@react-native-firebase/auth';

// 1. Sign Up with Email/Password
const signUp = async (email, password) => {
  try {
    const userCredential = await auth().createUserWithEmailAndPassword(
      email,
      password
    );
    console.log('User created:', userCredential.user.uid);
  } catch (error) {
    if (error.code === 'auth/email-already-in-use') {
      console.log('Email already exists');
    }
    if (error.code === 'auth/weak-password') {
      console.log('Password too weak');
    }
  }
};

// 2. Sign In
const signIn = async (email, password) => {
  try {
    const userCredential = await auth().signInWithEmailAndPassword(
      email,
      password
    );
    console.log('Signed in:', userCredential.user.email);
  } catch (error) {
    console.log('Login failed:', error.message);
  }
};

// 3. Sign Out
const signOut = async () => {
  await auth().signOut();
  console.log('User signed out');
};

// 4. Check if User is Logged In
const checkAuthState = () => {
  auth().onAuthStateChanged((user) => {
    if (user) {
      console.log('User is logged in:', user.email);
    } else {
      console.log('No user logged in');
    }
  });
};

// 5. Google Sign In
import { GoogleSignin } from '@react-native-google-signin/google-signin';

const signInWithGoogle = async () => {
  // Get Google credentials
  const { idToken } = await GoogleSignin.signIn();

  // Create Firebase credential
  const googleCredential = auth.GoogleAuthProvider.credential(idToken);

  // Sign in to Firebase
  return auth().signInWithCredential(googleCredential);
};

// 6. Reset Password
const resetPassword = async (email) => {
  await auth().sendPasswordResetEmail(email);
  console.log('Password reset email sent');
};

Cloud Firestore

Firestore is a NoSQL cloud database that stores data in documents and collections. Think of it like a filing cabinet: collections are drawers, documents are folders, and fields are the papers inside folders.

Data Structure

Firestore Structure:
┌─────────────────────────────────┐
│ Collection: "users"             │
│  ├─ Document: "user123"         │
│  │   ├─ name: "Alice"           │
│  │   ├─ email: "alice@..."      │
│  │   └─ age: 25                 │
│  └─ Document: "user456"         │
│      ├─ name: "Bob"             │
│      └─ email: "bob@..."        │
│                                 │
│ Collection: "posts"             │
│  ├─ Document: "post1"           │
│  │   ├─ title: "Hello"          │
│  │   ├─ content: "..."          │
│  │   └─ authorId: "user123"     │
│  └─ Document: "post2"           │
└─────────────────────────────────┘
// Install Firestore
npm install @react-native-firebase/firestore

import firestore from '@react-native-firebase/firestore';

// 1. Add Data (Create)
const addUser = async () => {
  await firestore().collection('users').add({
    name: 'Alice',
    email: 'alice@example.com',
    age: 25,
    createdAt: firestore.FieldValue.serverTimestamp()
  });
  console.log('User added');
};

// Add with custom ID
const addUserWithId = async () => {
  await firestore().collection('users').doc('user123').set({
    name: 'Bob',
    email: 'bob@example.com'
  });
};

// 2. Read Data (Get)
const getUser = async (userId) => {
  const userDoc = await firestore().collection('users').doc(userId).get();

  if (userDoc.exists) {
    console.log('User data:', userDoc.data());
  } else {
    console.log('User not found');
  }
};

// Get all users
const getAllUsers = async () => {
  const snapshot = await firestore().collection('users').get();

  snapshot.forEach(doc => {
    console.log(doc.id, '=>', doc.data());
  });
};

// 3. Update Data
const updateUser = async (userId) => {
  await firestore().collection('users').doc(userId).update({
    age: 26,
    city: 'New York'
  });
};

// 4. Delete Data
const deleteUser = async (userId) => {
  await firestore().collection('users').doc(userId).delete();
};

// 5. Real-time Updates (Listen to changes)
const listenToUser = (userId) => {
  // Data updates automatically when changed in database
  const unsubscribe = firestore()
    .collection('users')
    .doc(userId)
    .onSnapshot(doc => {
      console.log('User updated:', doc.data());
    });

  // Stop listening when component unmounts
  return unsubscribe;
};

// 6. Queries
const getAdultUsers = async () => {
  const snapshot = await firestore()
    .collection('users')
    .where('age', '>=', 18)
    .orderBy('age', 'desc')
    .limit(10)
    .get();

  snapshot.forEach(doc => {
    console.log(doc.data());
  });
};

// 7. Complete CRUD Example
const TodoApp = () => {
  const [todos, setTodos] = useState([]);

  useEffect(() => {
    // Real-time listener
    const unsubscribe = firestore()
      .collection('todos')
      .orderBy('createdAt', 'desc')
      .onSnapshot(snapshot => {
        const todoList = snapshot.docs.map(doc => ({
          id: doc.id,
          ...doc.data()
        }));
        setTodos(todoList);
      });

    return () => unsubscribe();
  }, []);

  const addTodo = async (text) => {
    await firestore().collection('todos').add({
      text: text,
      completed: false,
      createdAt: firestore.FieldValue.serverTimestamp()
    });
  };

  const toggleTodo = async (id, completed) => {
    await firestore().collection('todos').doc(id).update({
      completed: !completed
    });
  };

  const deleteTodo = async (id) => {
    await firestore().collection('todos').doc(id).delete();
  };

  return (
    // Render todos...
  );
};

Cloud Storage

Cloud Storage is for uploading and storing files like images, videos, and documents. Think of it like Dropbox or Google Drive for your app's files.

// Install Storage
npm install @react-native-firebase/storage

import storage from '@react-native-firebase/storage';

// 1. Upload Image from Camera/Gallery
const uploadImage = async (uri) => {
  const filename = uri.substring(uri.lastIndexOf('/') + 1);
  const reference = storage().ref(`images/${filename}`);

  // Show upload progress
  const task = reference.putFile(uri);

  task.on('state_changed', snapshot => {
    const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
    console.log(`Upload is ${progress}% done`);
  });

  await task;

  // Get download URL
  const downloadURL = await reference.getDownloadURL();
  console.log('Image uploaded:', downloadURL);

  return downloadURL;
};

// 2. Upload with Metadata
const uploadWithMetadata = async (uri) => {
  const reference = storage().ref('profile-photos/user123.jpg');

  await reference.putFile(uri, {
    contentType: 'image/jpeg',
    customMetadata: {
      uploadedBy: 'user123',
      location: 'New York'
    }
  });
};

// 3. Download File
const downloadImage = async () => {
  const url = await storage()
    .ref('images/photo.jpg')
    .getDownloadURL();

  // Use URL to display in Image component
  return url;
};

// 4. Delete File
const deleteImage = async (path) => {
  await storage().ref(path).delete();
};

// 5. Complete Profile Photo Example
const ProfilePhotoUpload = () => {
  const [uploading, setUploading] = useState(false);
  const [photoURL, setPhotoURL] = useState(null);

  const selectAndUploadPhoto = async () => {
    // Pick image from gallery
    const result = await ImagePicker.launchImageLibrary({
      mediaType: 'photo',
      quality: 0.5
    });

    if (result.assets && result.assets[0]) {
      setUploading(true);
      const uri = result.assets[0].uri;

      try {
        // Upload to Firebase Storage
        const userId = auth().currentUser.uid;
        const reference = storage().ref(`profile-photos/${userId}.jpg`);
        await reference.putFile(uri);

        // Get download URL
        const url = await reference.getDownloadURL();

        // Save URL to Firestore user document
        await firestore().collection('users').doc(userId).update({
          photoURL: url
        });

        setPhotoURL(url);
      } catch (error) {
        console.error('Upload failed:', error);
      } finally {
        setUploading(false);
      }
    }
  };

  return (
    <View>
      {photoURL && <Image source={{ uri: photoURL }} />}
      <Button title="Upload Photo" onPress={selectAndUploadPhoto} />
      {uploading && <ActivityIndicator />}
    </View>
  );
};

Cloud Functions

Cloud Functions are like having a backend developer who writes code that runs on Google's servers automatically in response to events. Think of them as mini-programs that wake up when something happens (user signs up, data changes, etc.)

Common Use Cases

  • Send Welcome Emails: When user signs up
  • Image Processing: Resize photos when uploaded
  • Data Validation: Check data before saving
  • Notifications: Send push notifications
  • Scheduled Tasks: Daily cleanup, reports
  • Payment Processing: Integrate with Stripe
// Cloud Functions are written in Node.js
// Deploy with: firebase deploy --only functions

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();

// 1. Trigger when new user signs up
exports.sendWelcomeEmail = functions.auth.user().onCreate((user) => {
  console.log('New user:', user.email);
  // Send email using SendGrid, Mailgun, etc.
  return sendEmail(user.email, 'Welcome!', 'Thanks for signing up!');
});

// 2. Trigger when document is created
exports.onNewPost = functions.firestore
  .document('posts/{postId}')
  .onCreate((snapshot, context) => {
    const post = snapshot.data();
    const postId = context.params.postId;

    // Send notification to followers
    return sendNotificationToFollowers(post.authorId, postId);
  });

// 3. Trigger when image is uploaded
exports.generateThumbnail = functions.storage.object().onFinalize((object) => {
  const filePath = object.name;

  if (!filePath.startsWith('images/')) {
    return null;
  }

  // Generate thumbnail using Sharp library
  return generateThumbnailFromImage(filePath);
});

// 4. HTTP Callable Function (call from app)
exports.addPremiumRole = functions.https.onCall(async (data, context) => {
  // Check authentication
  if (!context.auth) {
    throw new functions.https.HttpsError(
      'unauthenticated',
      'User must be logged in'
    );
  }

  const userId = context.auth.uid;

  // Add premium role to user
  await admin.auth().setCustomUserClaims(userId, {
    premium: true
  });

  return { success: true };
});

// Call from React Native:
// import functions from '@react-native-firebase/functions';
// const result = await functions().httpsCallable('addPremiumRole')();

// 5. Scheduled Function (cron job)
exports.dailyCleanup = functions.pubsub
  .schedule('every day 00:00')
  .onRun(async (context) => {
    // Delete old temporary data
    const cutoff = Date.now() - 30 * 24 * 60 * 60 * 1000; // 30 days ago

    const snapshot = await admin.firestore()
      .collection('temp')
      .where('createdAt', '<', cutoff)
      .get();

    const batch = admin.firestore().batch();
    snapshot.docs.forEach(doc => batch.delete(doc.ref));
    await batch.commit();

    console.log(`Deleted ${snapshot.size} old documents`);
  });

Security Rules

Security rules protect your data by controlling who can read or write. Think of them as security guards who check IDs before letting people access data.

// Firestore Security Rules
rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {

    // Anyone can read, only authenticated users can write
    match /posts/{postId} {
      allow read: if true;
      allow create: if request.auth != null;
      allow update, delete: if request.auth.uid == resource.data.authorId;
    }

    // Users can only access their own data
    match /users/{userId} {
      allow read, write: if request.auth.uid == userId;
    }

    // Only admins can access admin collection
    match /admin/{document=**} {
      allow read, write: if request.auth.token.admin == true;
    }

    // Validate data before writing
    match /products/{productId} {
      allow create: if request.resource.data.name is string
                    && request.resource.data.price is number
                    && request.resource.data.price > 0;
    }
  }
}

// Storage Security Rules
rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {

    // Users can only upload to their own folder
    match /users/{userId}/{allPaths=**} {
      allow read: if true;
      allow write: if request.auth.uid == userId;
    }

    // Images only, max 5MB
    match /images/{imageId} {
      allow write: if request.resource.size < 5 * 1024 * 1024
                   && request.resource.contentType.matches('image/.*');
    }
  }
}

Firebase vs Custom Backend

Aspect Firebase (BaaS) Custom Backend
Setup Time Minutes Weeks/Months
Maintenance Google handles it You manage servers
Scaling Automatic Manual configuration
Cost (small app) Free/$25/month $50-200/month (server)
Flexibility Limited to Firebase features Complete control
Real-time Built-in Need WebSockets/Socket.io

Best Practices

  • Use Security Rules: Never leave database publicly accessible
  • Structure Data Wisely: Design collections for your query patterns
  • Optimize Images: Compress before uploading to save storage costs
  • Use Batch Writes: Group multiple writes for better performance
  • Cache Data: Don't fetch same data repeatedly
  • Monitor Usage: Watch Firebase console for costs and errors
  • Validate Data: Use security rules and Cloud Functions for validation
  • Handle Offline: Firebase has built-in offline support
  • Index Queries: Create indexes for complex queries
  • Limit Data: Use pagination, don't load thousands of documents at once

Getting Started

# 1. Create Firebase project at firebase.google.com

# 2. Install Firebase CLI
npm install -g firebase-tools

# 3. Login to Firebase
firebase login

# 4. Initialize Firebase in your project
firebase init

# 5. Install React Native Firebase
npm install @react-native-firebase/app

# 6. Configure for iOS (ios/Podfile)
cd ios && pod install

# 7. Configure for Android (add google-services.json)

# 8. Install specific services
npm install @react-native-firebase/auth
npm install @react-native-firebase/firestore
npm install @react-native-firebase/storage

Ready to Build with Firebase?

Master Firebase and create powerful mobile apps without backend code

Explore Hybrid Mobile App Course

Related Topics