Firebase : backend sans serveur pour applications web

🏷️ Cloud && Déploiement 📅 12/04/2026 13:00:00 👤 Mezgani Said
Firebase Serverless Backend Application Realtime Database
Firebase : backend sans serveur pour applications web

Découvrir Firebase pour construire un backend sans serveur. Authentification, Firestore, Storage et déploiement hosting avec Firebase.

Introduction à Firebase et serverless

Firebase est une plateforme backend complète de Google qui permet de construire des applications sans gérer de serveurs. C'est l'approche serverless : vous écrivez le code, Firebase gère l'infrastructure.

À retenir : Firebase = BaaS (Backend as a Service). Pas de serveurs à gérer, scalabilité automatique, facturée à l'usage.

Services Firebase :

  • Authentification → Gestion des utilisateurs et tokens
  • Firestore → Base de données NoSQL temps réel
  • Realtime Database → Alternative NoSQL avec sync temps réel
  • Cloud Storage → Stockage de fichiers (images, vidéos)
  • Cloud Functions → Serverless computing pour votre logique métier
  • Hosting → Déployer votre app statique avec CDN
  • Analytics → Tracking d'événements utilisateurs

Avantages Firebase :

  • ✅ Développement ultra-rapide (0 serveur à configurer)
  • ✅ Scalabilité automatique (gère la charge)
  • ✅ Pricing flexible (payez que ce que vous utilisez)
  • ✅ Excellente documentation et SDK
  • ✅ PAS de DevOps à gérer

Configuration d'un projet Firebase

Étape 1 : Créer un compte Firebase

  1. Aller sur firebase.google.com
  2. Se connecter avec Google (ou créer un compte)
  3. Cliquer sur "Create a project"

Étape 2 : Initialiser le projet

$ npm install -g firebase-tools
$ firebase login
$ firebase init

# Sélectionner :
# - Realtime Database
# - Firestore
# - Cloud Functions
# - Hosting
# - Emulator

Étape 3 : Structure du projet généré

firebase-project/
├── .firebaserc          # Configuration Firebase
├── firebase.json        # Configuration du projet
├── firestore.rules      # Règles Firestore (sécurité)
├── public/              # Dossier pour Hosting
├── functions/           # Cloud Functions
│   ├── index.js
│   └── package.json
└── .emulator/           # Emulators locaux

Étape 4 : Déployer

$ firebase deploy              # Deploy tout
$ firebase deploy --only hosting  # Deploy uniquement Hosting
$ firebase deploy --only functions # Deploy uniquement Functions

Authentification Firebase

Setup Authentication :

Dans Firebase Console → Authentication → Enable Email/Password

Inscription et connexion :

import { initializeApp } from 'firebase/app';
import { getAuth, createUserWithEmailAndPassword, signInWithEmailAndPassword } from 'firebase/auth';

const firebaseConfig = {
    apiKey: "YOUR_API_KEY",
    authDomain: "your-project.firebaseapp.com",
    projectId: "your-project",
    storageBucket: "your-project.appspot.com",
    messagingSenderId: "123456",
    appId: "1:123456:web:abc123"
};

const app = initializeApp(firebaseConfig);
const auth = getAuth(app);

// Inscription
const signup = async (email, password) => {
    try {
        const userCredential = await createUserWithEmailAndPassword(auth, email, password);
        return userCredential.user;
    } catch (error) {
        console.error('Error:', error.message);
    }
};

// Connexion
const login = async (email, password) => {
    try {
        const userCredential = await signInWithEmailAndPassword(auth, email, password);
        return userCredential.user;
    } catch (error) {
        console.error('Error:', error.message);
    }
};

Écouter les changements d'authentification :

import { onAuthStateChanged } from 'firebase/auth';

onAuthStateChanged(auth, (user) => {
    if (user) {
        console.info('Utilisateur connecté :', user.email);
        console.info('UID :', user.uid);
    } else {
        console.info('Utilisateur non connecté');
    }
});

Firestore : base de données temps réel

Créer et récupérer des documents :

import { getFirestore, collection, addDoc, getDocs, query, where } from 'firebase/firestore';

const db = getFirestore(app);

// Ajouter un document
const addPost = async (title, content, author) => {
    try {
        const docRef = await addDoc(collection(db, "posts"), {
            title,
            content,
            author,
            createdAt: new Date(),
            likes: 0
        });
        console.info('Document ID:', docRef.id);
    } catch (error) {
        console.error('Error adding document:', error);
    }
};

// Récupérer tous les documents
const getPosts = async () => {
    try {
        const querySnapshot = await getDocs(collection(db, "posts"));
        const posts = [];
        querySnapshot.forEach((doc) => {
            posts.push({ id: doc.id, ...doc.data() });
        });
        return posts;
    } catch (error) {
        console.error('Error:', error);
    }
};

// Requête avec filtre
const getPostsByAuthor = async (author) => {
    try {
        const q = query(collection(db, "posts"), where("author", "==", author));
        const querySnapshot = await getDocs(q);
        return querySnapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }));
    } catch (error) {
        console.error('Error:', error);
    }
};

Écoute temps réel (Realtime Listener) :

import { onSnapshot } from 'firebase/firestore';

// S'abonner aux changements en temps réel
onSnapshot(collection(db, "posts"), (snapshot) => {
    const posts = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }));
    console.info('Posts updated:', posts);
    // Mettre à jour l'UI
});

Mettre à jour et supprimer :

import { updateDoc, deleteDoc, doc } from 'firebase/firestore';

// Mettre à jour
const updatePost = async (postId, updates) => {
    await updateDoc(doc(db, "posts", postId), updates);
};

// Supprimer
const deletePost = async (postId) => {
    await deleteDoc(doc(db, "posts", postId));
};

Cloud Storage pour les fichiers

Uploader un fichier :

import { getStorage, ref, uploadBytes, getDownloadURL } from 'firebase/storage';

const storage = getStorage(app);

const uploadFile = async (file) => {
    try {
        const storageRef = ref(storage, `uploads/${file.name}`);
        const snapshot = await uploadBytes(storageRef, file);
        const downloadUrl = await getDownloadURL(snapshot.ref);
        console.info('File available at:', downloadUrl);
        return downloadUrl;
    } catch (error) {
        console.error('Upload error:', error);
    }
};

// Utilisation avec un input file
const handleFileUpload = async (event) => {
    const file = event.target.files[0];
    const url = await uploadFile(file);
};

Afficher une image uploadée :

<input type="file" onChange={handleFileUpload} />
<img id="preview" src="" alt="Uploaded" />

// Dans handleFileUpload :
const url = await uploadFile(file);
document.getElementById('preview').src = url;

Cloud Functions pour la logique serveur

Créer une Cloud Function (Node.js) :

// functions/index.js
const functions = require('firebase-functions');
const admin = require('firebase-admin');

admin.initializeApp();

// HTTP Trigger
exports.helloWorld = functions.https.onRequest((request, response) => {
    response.send("Hello from Firebase Cloud Functions!");
});

// Firestore Trigger (sur création de document)
exports.onPostCreated = functions.firestore
    .document('posts/{postId}')
    .onCreate((snap, context) => {
        const post = snap.data();
        console.info('Nouveau post créé:', post.title);
        // Logique (envoyer email, webhook, etc.)
    });

// Callable function depuis le client
exports.addNumbers = functions.https.onCall((data, context) => {
    return { result: data.a + data.b };
});

Appeler une function depuis le client :

import { getFunctions, httpsCallable } from 'firebase/functions';

const functions = getFunctions(app);
const addNumbers = httpsCallable(functions, 'addNumbers');

const result = await addNumbers({ a: 5, b: 3 });
console.info(result.data.result); // 8

Firebase Hosting

Déployer une app statique :

$ cd public/
$ npm run build  # Générer les fichiers statiques

$ firebase deploy --only hosting

Configuration Firebase Hosting (firebase.json) :

{
    "hosting": {
        "public": "dist",
        "ignore": ["firebase.json", "**/.*"],
        "rewrites": [
            {
                "source": "**",
                "destination": "/index.html"
            }
        ],
        "headers": [
            {
                "source": "/**",
                "headers": [
                    {
                        "key": "Cache-Control",
                        "value": "public, max-age=31536000"
                    }
                ]
            }
        ]
    }
}

Avantages de Firebase Hosting :

  • ✅ CDN global automatique
  • ✅ HTTPS par défaut
  • ✅ Déploiement en 1 ligne
  • ✅ Redirections et headers simplifiés

Intégration avec Angular/React/Vue

React avec Firebase :

import { useEffect, useState } from 'react';
import { collection, onSnapshot } from 'firebase/firestore';
import { db } from './firebase-config';

function PostsList() {
    const [posts, setPosts] = useState([]);

    useEffect(() => {
        const unsubscribe = onSnapshot(collection(db, "posts"), (snapshot) => {
            const newPosts = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }));
            setPosts(newPosts);
        });

        return unsubscribe; // Cleanup
    }, []);

    return (
        <ul>
            {posts.map(post => <li key={post.id}>{post.title}</li>)}
        </ul>
    );
}

Angular avec Firebase :

import { Injectable } from '@angular/core';
import { Firestore, collection, collectionData } from '@angular/fire/firestore';
import { Observable } from 'rxjs';

@Injectable({ providedIn: 'root' })
export class PostService {
    constructor(private firestore: Firestore) {}

    getPosts(): Observable<any> {
        const col = collection(this.firestore, 'posts');
        return collectionData(col, { idField: 'id' });
    }
}

Vue avec Firebase :

import { ref, onMounted } from 'vue';
import { collection, onSnapshot } from 'firebase/firestore';
import { db } from './firebase-config';

export default {
    setup() {
        const posts = ref([]);

        onMounted(() => {
            onSnapshot(collection(db, "posts"), (snapshot) => {
                posts.value = snapshot.docs.map(doc => ({
                    id: doc.id,
                    ...doc.data()
                }));
            });
        });

        return { posts };
    }
}

Performance et bonnes pratiques

Règles de sécurité Firestore (firestore.rules) :

rules_version = '2';
service cloud.firestore {
    match /databases/{database}/documents {
        // Permettre lecture/écriture si authentifié
        match /posts/{document=**} {
            allow read, write: if request.auth != null;
        }

        // Seulement le propriétaire peut modifier son profil
        match /users/{userId} {
            allow read, write: if request.auth.uid == userId;
        }

        // Lecture publique, écriture limitée
        match /public/{document=**} {
            allow read: if true;
            allow write: if request.auth != null && request.auth.uid == request.resource.data.authorId;
        }
    }
}

Optimisations :

  • Indexing : Firebase crée les index automatiquement pour les requêtes
  • Pagination : Utiliser limit() et startAfter() pour paginer
  • Offline persistence : Firebase synchronise automatiquement quand la connexion revient
  • Batch writes : Regrouper plusieurs écritures pour plus d'efficacité
  • Unsubscribe : Ne pas oublier de se désabonner des listeners (memory leaks)

Monitoring et debugging :

$ firebase emulators:start     # Émuler localement
$ firebase serve               # Tester en local

Comparaison avec alternatives

Critère Firebase Supabase MongoDB Atlas
Type BD NoSQL (Firestore) PostgreSQL NoSQL (MongoDB)
Serverless ✅ Oui ⚠️ À configurer ✅ Atlas
Auth intégrée ✅ Excellent ✅ Très bon ❌ À faire soi-même
Hosting ✅ Oui ❌ Non ❌ Non
Prix (startup) 💚 Free tier généreux 💚 Gratuit ⚠️ Payant

Quand choisir Firebase :

  • ✅ MVP et prototypes rapides
  • ✅ Applications avec pics d'utilisation imprévisibles
  • ✅ Équipe petite (0 DevOps)
  • ✅ Applications temps réel (chat, notifications)

Quand choisir une alternative :

  • ❌ Requêtes SQL complexes → PostgreSQL (Supabase)
  • ❌ Besoin de contrôle total → VPS classique
  • ❌ Application très volumineuse → Infrastructure custom
Conclusion : Firebase est excellent pour les développeurs qui veulent se concentrer sur le code plutôt que l'infrastructure. Scalabilité garantie, pas de DevOps, et déploiement instantané. Le choix parfait pour les startups et les équipes de petite/moyenne taille.