Comment Utiliser l'API Firebase: Guide d'Intégration Complet (2026)

Ashley Innocent

Ashley Innocent

23 March 2026

Comment Utiliser l'API Firebase: Guide d'Intégration Complet (2026)

Vous développez une application. Les utilisateurs doivent se connecter. Les données doivent se synchroniser en temps réel. Les fichiers nécessitent un stockage. Vous pourriez déployer des serveurs, configurer des bases de données et gérer l'infrastructure pendant des semaines. Ou vous pourriez utiliser Firebase.

Firebase alimente plus de 1,5 million d'applications, dont The New York Times, Duolingo et Alibaba. Les développeurs le choisissent car il élimine la complexité du backend. Vous vous concentrez sur les fonctionnalités, pas sur la maintenance des serveurs. Mais l'API Firebase a ses particularités. Les flux d'authentification déroutent les débutants. Les règles de base de données piègent les développeurs expérimentés. Les fonctions Cloud semblent magiques jusqu'à ce que vous compreniez les déclencheurs.

J'ai intégré Firebase dans des applications de production servant des millions d'utilisateurs. J'ai commis toutes les erreurs possibles : exposé des clés de compte de service, écrit des requêtes inefficaces, déployé des fonctions défectueuses. Ce guide condense ces leçons.

Vous apprendrez l'authentification, les opérations de base de données, les fonctions Cloud et le stockage. Vous verrez du code fonctionnel, pas seulement de la théorie. Vous éviterez les pièges qui causent des problèmes en production.

💡
Tester les API Firebase devient plus facile avec des outils clients API appropriés. Apidog vous permet d'organiser les points d'accès, de tester les flux d'authentification et de partager des collections avec votre équipe. Nous vous montrerons où il s'intègre naturellement dans le flux de travail.
bouton

Qu'est-ce que l'API Firebase et pourquoi est-elle importante ?

Firebase n'est pas une seule API. C'est une suite de services backend accessibles via des SDK unifiés et des points d'accès REST.

Services Firebase principaux

Service Objectif Type d'API
Authentification Connexion et identité de l'utilisateur SDK + REST
Base de données Firestore Base de données de documents NoSQL SDK + REST
Base de données en temps réel Synchronisation JSON en temps réel SDK + REST
Cloud Storage Stockage de fichiers et CDN SDK + REST
Cloud Functions Calcul sans serveur CLI de déploiement
Hébergement Hébergement web statique CLI de déploiement
Cloud Messaging Notifications push API HTTP v1

Quand Firebase est pertinent

Firebase résout bien des problèmes spécifiques :

Utilisez Firebase lorsque :

Évitez Firebase lorsque :

L'architecture de l'API Firebase

Firebase utilise une approche hybride :

┌─────────────────────────────────────────────────────────┐
│                    Votre application                     │
├─────────────────────────────────────────────────────────┤
│  SDK Firebase (Client)                                  │
│  - Gère automatiquement les jetons d'authentification   │
│  - Gère le cache hors ligne                              │
│  - Écouteurs en temps réel                               │
└─────────────────────────────────────────────────────────┘
                          │
                          │ HTTPS + WebSocket
                          ▼
┌─────────────────────────────────────────────────────────┐
│                   Backend Firebase                       │
├──────────────┬──────────────┬──────────────┬────────────┤
│   Service    │  Base de     │   Service    │ Runtime    │
│   d'Auth.    │  données     │   de Stock.  │  des Fcts  │
│              │  Firestore   │              │            │
└──────────────┴──────────────┴──────────────┴────────────┘

Les SDK clients abstraient la couche HTTP. En arrière-plan, chaque opération se traduit par des appels d'API REST avec authentification JWT.

Authentification Firebase : Configuration complète

L'authentification est votre première intégration Firebase. Si cela échoue, tout le reste échoue.

Étape 1 : Créer un projet Firebase

  1. Allez à la Console Firebase
Capture d'écran de la console Firebase montrant le bouton « Ajouter un projet »

Cliquez sur "Ajouter un projet" et saisissez le nom du projet (pas d'espaces)

Capture d'écran de l'étape de saisie du nom du projet dans la console Firebase

Activez Google Analytics (facultatif mais recommandé)

Capture d'écran de l'étape d'activation de Google Analytics pour un projet Firebase

Cliquez sur "Créer le projet"

Capture d'écran de l'étape finale de création d'un projet Firebase

Attendez 30 secondes pour le provisionnement. Vous verrez le tableau de bord du projet.

Étape 2 : Enregistrer votre application

Pour les applications web :

// Dans la console Firebase > Paramètres du projet > Général
// Cliquez sur "Ajouter une application" > icône Web

// Enregistrer l'application web
const firebaseConfig = {
  apiKey: "AIzaSyDxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  authDomain: "your-app.firebaseapp.com",
  projectId: "your-app",
  storageBucket: "your-app.appspot.com",
  messagingSenderId: "123456789012",
  appId: "1:123456789012:web:abc123def456"
};

// Initialiser Firebase
import { initializeApp } from 'firebase/app';
const app = initializeApp(firebaseConfig);

Pour les applications iOS :

Téléchargez GoogleService-Info.plist et ajoutez-le au projet Xcode. Assurez-vous que "Target Membership" inclut votre application.

Pour les applications Android :

Téléchargez google-services.json et placez-le dans le répertoire app/. Ajoutez à build.gradle :

// build.gradle au niveau du projet
buildscript {
    dependencies {
        classpath 'com.google.gms:google-services:4.4.0'
    }
}

// build.gradle au niveau de l'application
plugins {
    id 'com.google.gms.google-services'
}

Étape 3 : Activer les méthodes d'authentification

Dans la console Firebase > Authentification > Méthode de connexion :

  1. E-mail/Mot de passe : Activez pour une inscription traditionnelle
  2. Google : Ajoutez votre empreinte de certificat SHA-1 (Android) ou l'ID de bundle (iOS)
  3. Apple : Obligatoire pour les applications iOS si vous activez une connexion sociale
  4. Téléphone : Activez pour l'authentification par SMS (nécessite une facturation)

Étape 4 : Implémenter le flux d'authentification

Inscription par e-mail/mot de passe :

import {
  createUserWithEmailAndPassword,
  getAuth,
  updateProfile
} from 'firebase/auth';

const auth = getAuth(app);

async function signUp(email, password, displayName) {
  try {
    const userCredential = await createUserWithEmailAndPassword(
      auth,
      email,
      password
    );

    // Définir le nom d'affichage
    await updateProfile(userCredential.user, {
      displayName: displayName
    });

    console.log('Utilisateur créé :', userCredential.user.uid);
    return userCredential.user;
  } catch (error) {
    // Gérer les codes d'erreur spécifiques
    switch (error.code) {
      case 'auth/email-already-in-use':
        throw new Error('Cet e-mail est déjà enregistré');
      case 'auth/weak-password':
        throw new Error('Le mot de passe doit contenir au moins 6 caractères');
      case 'auth/invalid-email':
        throw new Error('Adresse e-mail invalide');
      default:
        throw new Error("L'inscription a échoué : " + error.message);
    }
  }
}

Connexion par e-mail/mot de passe :

import {
  signInWithEmailAndPassword,
  signOut
} from 'firebase/auth';

async function signIn(email, password) {
  try {
    const userCredential = await signInWithEmailAndPassword(
      auth,
      email,
      password
    );

    const user = userCredential.user;

    // Obtenir le jeton d'identification pour les appels API
    const idToken = await user.getIdToken();
    console.log('Jeton d\'authentification :', idToken);

    return user;
  } catch (error) {
    switch (error.code) {
      case 'auth/user-not-found':
        throw new Error('Aucun compte avec cet e-mail');
      case 'auth/wrong-password':
        throw new Error('Mot de passe incorrect');
      case 'auth/too-many-requests':
        throw new Error('Trop de tentatives. Réessayez plus tard');
      default:
        throw new Error('La connexion a échoué');
    }
  }
}

async function logOut() {
  await signOut(auth);
  console.log('Utilisateur déconnecté');
}

Connexion Google (Web) :

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

async function signInWithGoogle() {
  const provider = new GoogleAuthProvider();

  // Demander des étendues supplémentaires
  provider.addScope('email');
  provider.addScope('profile');

  try {
    const result = await signInWithPopup(auth, provider);
    const user = result.user;

    // Accéder au jeton OAuth Google
    const credential = GoogleAuthProvider.credentialFromResult(result);
    const googleAccessToken = credential.accessToken;

    return user;
  } catch (error) {
    if (error.code === 'auth/popup-closed-by-user') {
      throw new Error("Connexion annulée");
    }
    throw new Error('La connexion Google a échoué');
  }
}

Étape 5 : Protéger les routes avec l'état d'authentification

import { onAuthStateChanged } from 'firebase/auth';

// S'abonner aux changements d'état d'authentification
onAuthStateChanged(auth, (user) => {
  if (user) {
    // L'utilisateur est connecté
    console.log('Utilisateur :', user.email);
    // Rediriger vers le tableau de bord
    window.location.href = '/dashboard';
  } else {
    // L'utilisateur est déconnecté
    console.log('Aucun utilisateur');
    // Rediriger vers la page de connexion
    window.location.href = '/login';
  }
});

Erreurs d'authentification courantes

Erreur 1 : Ne pas gérer le rafraîchissement des jetons

Le SDK Firebase rafraîchit automatiquement les jetons. Mais si vous mettez en cache les jetons côté serveur, ils expirent après 1 heure. Vérifiez toujours les jetons à chaque requête ou implémentez une logique de rafraîchissement.

Erreur 2 : Exposer les identifiants d'administrateur dans le code client

N'utilisez jamais les clés de compte de service dans les applications clientes. Les comptes de service contournent les règles de sécurité. Utilisez-les uniquement dans des environnements serveur de confiance.

Erreur 3 : Oublier la vérification de l'e-mail

import { sendEmailVerification } from 'firebase/auth';

async function sendVerificationEmail(user) {
  await sendEmailVerification(user);
  console.log('E-mail de vérification envoyé');
}

// Vérifier l'état de la vérification
if (!auth.currentUser.emailVerified) {
  console.log('E-mail non vérifié');
  // Restreindre l'accès
}

Base de données Firestore : Opérations et requêtes

Firestore est la base de données NoSQL de Firebase. Les documents sont organisés en collections. Les requêtes s'adaptent automatiquement.

Structure des données

votre-projet (racine)
└── utilisateurs (collection)
    ├── userId123 (document)
    │   ├── nom: "Jean"
    │   ├── email: "jean@example.com"
    │   └── publications (sous-collection)
    │       ├── postId1 (document)
    │       └── postId2 (document)
    └── userId456 (document)

Initialiser Firestore

import { getFirestore } from 'firebase/firestore';

const db = getFirestore(app);

Créer des documents

import {
  collection,
  addDoc,
  setDoc,
  doc
} from 'firebase/firestore';

// Option 1 : ID auto-généré
async function createUser(userData) {
  const docRef = await addDoc(collection(db, 'users'), userData);
  console.log('Document écrit avec l\'ID :', docRef.id);
  return docRef.id;
}

// Option 2 : ID personnalisé
async function createUserWithId(userId, userData) {
  await setDoc(doc(db, 'users', userId), userData);
  console.log('Document écrit avec l\'ID personnalisé :', userId);
}

// Utilisation
const userId = await createUser({
  name: 'Alice',
  email: 'alice@example.com',
  createdAt: new Date(),
  role: 'user'
});

Lire des documents

import {
  getDoc,
  getDocs,
  query,
  where,
  orderBy,
  limit
} from 'firebase/firestore';

// Obtenir un seul document
async function getUser(userId) {
  const docRef = doc(db, 'users', userId);
  const docSnap = await getDoc(docRef);

  if (docSnap.exists()) {
    return docSnap.data();
  } else {
    throw new Error('Utilisateur non trouvé');
  }
}

// Requête avec filtres
async function getUsersByRole(role) {
  const q = query(
    collection(db, 'users'),
    where('role', '==', role),
    orderBy('createdAt', 'desc'),
    limit(10)
  );

  const querySnapshot = await getDocs(q);
  const users = [];

  querySnapshot.forEach((doc) => {
    users.push({ id: doc.id, ...doc.data() });
  });

  return users;
}

// Utilisation
const adminUsers = await getUsersByRole('admin');
console.log('Utilisateurs administrateurs :', adminUsers);

Mettre à jour des documents

import {
  updateDoc,
  increment,
  arrayUnion,
  arrayRemove
} from 'firebase/firestore';

async function updateUser(userId, updates) {
  const userRef = doc(db, 'users', userId);
  await updateDoc(userRef, updates);
}

// Opérations atomiques
await updateUser('userId123', {
  loginCount: increment(1),
  tags: arrayUnion('premium', 'beta-tester'),
  lastLogin: new Date()
});

// Supprimer d'un tableau
await updateUser('userId123', {
  tags: arrayRemove('beta-tester')
});

Supprimer des documents

import { deleteDoc } from 'firebase/firestore';

async function deleteUser(userId) {
  await deleteDoc(doc(db, 'users', userId));
  console.log('Utilisateur supprimé');
}

Écouteurs en temps réel

import { onSnapshot } from 'firebase/firestore';

// Écouter un seul document
const unsubscribe = onSnapshot(
  doc(db, 'users', userId),
  (doc) => {
    console.log('Utilisateur mis à jour :', doc.data());
  },
  (error) => {
    console.error('Erreur d\'écoute :', error);
  }
);

// Écouter les résultats d'une requête
const q = query(collection(db, 'posts'), where('published', '==', true));

const unsubscribeQuery = onSnapshot(q, (snapshot) => {
  const posts = snapshot.docs.map(doc => ({
    id: doc.id,
    ...doc.data()
  }));
  console.log('Publications publiées :', posts);
});

// Arrêter d'écouter
unsubscribe();
unsubscribeQuery();

Règles de sécurité Firestore

Sans règles appropriées, n'importe qui peut lire vos données. Définissez les règles dans la console Firebase > Firestore > Règles :

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

    // Fonction d'aide
    function isAuthenticated() {
      return request.auth != null;
    }

    function isOwner(userId) {
      return request.auth.uid == userId;
    }

    // Collection des utilisateurs
    match /users/{userId} {
      allow read: if isAuthenticated();
      allow create: if isAuthenticated() && isOwner(userId);
      allow update, delete: if isOwner(userId);
    }

    // Collection des publications
    match /posts/{postId} {
      allow read: if true; // Lecture publique
      allow create: if isAuthenticated();
      allow update, delete: if resource.data.authorId == request.auth.uid;
    }

    // Sous-collection privée
    match /users/{userId}/private/{document} {
      allow read, write: if isOwner(userId);
    }
  }
}

Limitations des requêtes

Firestore a des contraintes :

Solution de contournement pour les requêtes OU :

// Au lieu de : where('status', '==', 'active') OU where('status', '==', 'pending')

const activeQuery = query(
  collection(db, 'tasks'),
  where('status', '==', 'active')
);

const pendingQuery = query(
  collection(db, 'tasks'),
  where('status', '==', 'pending')
);

const [activeSnap, pendingSnap] = await Promise.all([
  getDocs(activeQuery),
  getDocs(pendingQuery)
]);

// Fusionner les résultats côté client

Cloud Functions : Logique backend sans serveur

Les fonctions Cloud exécutent du code backend sans gérer de serveurs. Elles se déclenchent lors de modifications de base de données, de requêtes HTTP ou d'événements planifiés.

Configuration

# Installer Firebase CLI
npm install -g firebase-tools

# Connexion
firebase login

# Initialiser les fonctions dans votre projet
firebase init functions

# Sélectionner : JavaScript, ESLint oui, Express.js non

Fonctions HTTP (points d'accès API)

// functions/index.js
const { onRequest } = require('firebase-functions/v2/https');
const admin = require('firebase-admin');

admin.initializeApp();
const db = admin.firestore();

// Point d'accès public
exports.getPublicData = onRequest(async (req, res) => {
  res.set('Access-Control-Allow-Origin', '*');

  try {
    const snapshot = await db.collection('public').get();
    const data = snapshot.docs.map(doc => doc.data());
    res.json({ success: true, data });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// Point d'accès protégé (vérifier le jeton d'authentification)
exports.getUserProfile = onRequest(async (req, res) => {
  res.set('Access-Control-Allow-Origin', '*');

  // Obtenir le jeton de l'en-tête Authorization
  const authHeader = req.headers.authorization || '';
  const token = authHeader.split('Bearer ')[1];

  if (!token) {
    return res.status(401).json({ error: 'Non autorisé' });
  }

  try {
    // Vérifier le jeton
    const decodedToken = await admin.auth().verifyIdToken(token);
    const userId = decodedToken.uid;

    // Obtenir les données de l'utilisateur
    const userDoc = await db.collection('users').doc(userId).get();

    if (!userDoc.exists) {
      return res.status(404).json({ error: 'Utilisateur non trouvé' });
    }

    res.json({
      success: true,
      data: { id: userId, ...userDoc.data() }
    });
  } catch (error) {
    res.status(401).json({ error: 'Jeton invalide' });
  }
});

Déploiement :

firebase deploy --only functions:getUserProfile

Appel depuis le client :

async function getUserProfile(token) {
  const response = await fetch(
    'https://us-central1-your-app.cloudfunctions.net/getUserProfile',
    {
      headers: {
        'Authorization': `Bearer ${token}`
      }
    }
  );

  const data = await response.json();
  return data;
}

Déclencheurs de base de données

const { onDocumentWritten } = require('firebase-functions/v2/firestore');

// Déclencher lorsque le document utilisateur change
exports.onUserUpdate = onDocumentWritten(
  'users/{userId}',
  async (event) => {
    const userId = event.params.userId;
    const before = event.data?.before?.data();
    const after = event.data?.after?.data();

    // Vérifier si l'e-mail a changé
    if (before?.email !== after?.email) {
      console.log(`L'e-mail de l'utilisateur ${userId} a changé : ${before?.email} → ${after?.email}`);

      // Envoyer un e-mail de notification
      await admin.auth().getUser(userId);
      // Ajouter votre logique d'e-mail ici
    }
  }
);

// Déclencher lors de la création d'une nouvelle publication
exports.onNewPost = onDocumentWritten(
  'posts/{postId}',
  async (event) => {
    const post = event.data?.after?.data();

    if (!post) return; // Document supprimé

    // Vérifier s'il s'agit d'un nouveau document
    if (!event.data?.before?.exists) {
      console.log('Nouvelle publication créée :', post.title);

      // Notifier les abonnés
      const followersSnap = await admin.firestore()
        .collection('users')
        .where('following', 'array-contains', post.authorId)
        .get();

      const notifications = followersSnap.docs.map(doc => ({
        userId: doc.id,
        postId: event.params.postId,
        type: 'new_post',
        createdAt: admin.firestore.FieldValue.serverTimestamp()
      }));

      const batch = admin.firestore().batch();
      notifications.forEach(notif => {
        const ref = admin.firestore().collection('notifications').doc();
        batch.set(ref, notif);
      });

      await batch.commit();
    }
  }
);

Fonctions planifiées (tâches Cron)

const { onSchedule } = require('firebase-functions/v2/scheduler');

// Exécuter tous les jours à minuit UTC
exports.dailyCleanup = onSchedule('toutes les 24 heures', async (event) => {
  console.log('Exécution du nettoyage quotidien');

  // Supprimer les anciennes notifications (plus de 30 jours)
  const thirtyDaysAgo = new Date();
  thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);

  const oldNotifs = await admin.firestore()
    .collection('notifications')
    .where('createdAt', '<', thirtyDaysAgo)
    .get();

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

  console.log(`Supprimé ${oldNotifs.size} anciennes notifications`);
});

Configuration de l'environnement

# Définir les variables d'environnement
firebase functions:config:set \
  stripe.secret="sk_test_xxx" \
  email.api_key="key_xxx"

# Accéder aux fonctions
const config = require('firebase-functions/config');
const stripe = require('stripe')(config.stripe.secret);

Cloud Storage : Téléchargement et gestion de fichiers

Stockez les téléchargements d'utilisateurs, les images et les fichiers avec une distribution CDN automatique.

Configuration des règles de stockage

// Console Firebase > Stockage > Règles
rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {

    // Dossier des téléchargements d'utilisateurs
    match /users/{userId}/{allPaths=**} {
      allow read: if true; // Lecture publique
      allow write: if request.auth.uid == userId;
      allow delete: if request.auth.uid == userId;
    }

    // Actifs publics
    match /public/{allPaths=**} {
      allow read: if true;
      allow write: if false; // Administrateur uniquement via la console Firebase
    }
  }
}

Télécharger des fichiers (Client)

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

const storage = getStorage(app);

async function uploadProfileImage(userId, file) {
  // Créer une référence de stockage
  const storageRef = ref(storage, `users/${userId}/profile/${file.name}`);

  // Télécharger le fichier
  const uploadTask = uploadBytesResumable(storageRef, file);

  return new Promise((resolve, reject) => {
    uploadTask.on(
      'state_changed',
      (snapshot) => {
        // Suivre la progression
        const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
        console.log(`Téléchargement : ${progress.toFixed(0)}%`);
      },
      (error) => {
        // Gérer les erreurs
        switch (error.code) {
          case 'storage/unauthorized':
            reject(new Error('Vous n\'avez pas la permission'));
            break;
          case 'storage/canceled':
            reject(new Error('Téléchargement annulé'));
            break;
          default:
            reject(new Error('Le téléchargement a échoué'));
        }
      },
      async () => {
        // Téléchargement terminé
        const downloadURL = await getDownloadURL(uploadTask.snapshot.ref);
        console.log('Fichier disponible à :', downloadURL);
        resolve(downloadURL);
      }
    );
  });
}

// Utilisation
const fileInput = document.querySelector('input[type="file"]');
const file = fileInput.files[0];

if (file) {
  const imageUrl = await uploadProfileImage(auth.currentUser.uid, file);

  // Enregistrer l'URL dans Firestore
  await updateDoc(doc(db, 'users', auth.currentUser.uid), {
    profileImage: imageUrl
  });
}

Télécharger des fichiers

import { getDownloadURL } from 'firebase/storage';

async function getProfileImage(userId) {
  const imageRef = ref(storage, `users/${userId}/profile/avatar.png`);

  try {
    const url = await getDownloadURL(imageRef);
    return url;
  } catch (error) {
    if (error.code === 'storage/object-not-found') {
      return null; // Pas d'image de profil
    }
    throw error;
  }
}

Supprimer des fichiers

import { deleteObject } from 'firebase/storage';

async function deleteProfileImage(userId) {
  const imageRef = ref(storage, `users/${userId}/profile/avatar.png`);
  await deleteObject(imageRef);
  console.log('Image de profil supprimée');
}

Tester les API Firebase avec Apidog

Firebase fournit des API REST pour tous les services. Les tester directement aide à déboguer les problèmes et à comprendre les requêtes sous-jacentes.

Importer l'API REST Firebase

  1. Ouvrez Apidog
  2. Créez un nouveau projet : "Firebase API"
  3. Importez la spécification OpenAPI de la documentation Firebase
  4. Ou ajoutez manuellement des points d'accès :

Point d'accès REST Firestore :

POST https://firestore.googleapis.com/v1/projects/{projectId}/databases/(default)/documents
Authorization: Bearer {oauth2_token}
Content-Type: application/json

{
  "fields": {
    "name": { "stringValue": "John" },
    "email": { "stringValue": "john@example.com" },
    "age": { "integerValue": 30 }
  }
}

Point d'accès d'authentification :

POST https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key={api_key}
Content-Type: application/json

{
  "email": "user@example.com",
  "password": "secret123",
  "returnSecureToken": true
}

Tester le flux d'authentification

  1. Créer une requête : "Connexion"
  2. Définir la méthode : POST
  3. Ajouter l'e-mail/mot de passe dans le corps
  4. Enregistrer le jeton de réponse comme variable d'environnement
  5. Utiliser {{token}} dans les requêtes ultérieures

Déboguer les règles de sécurité

Utilisez la suite d'émulateurs Firebase pour les tests locaux :

# Démarrer l'émulateur
firebase emulators:start

# Tester contre Firestore local
# http://localhost:8080

Bonnes pratiques de production

1. Implémenter une gestion d'erreurs appropriée

// Logique de réessai pour les échecs transitoires
async function firestoreWithRetry(operation, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await operation();
    } catch (error) {
      if (
        error.code === 'unavailable' ||
        error.code === 'deadline-exceeded'
      ) {
        const delay = Math.pow(2, i) * 1000; // Recul exponentiel
        await new Promise(resolve => setTimeout(resolve, delay));
        continue;
      }
      throw error;
    }
  }
}

2. Optimiser les performances des requêtes

Ajoutez des index composites pour les requêtes multi-champs :

// Cette requête nécessite un index composite
const q = query(
  collection(db, 'posts'),
  where('category', '==', 'tech'),
  where('views', '>', 1000),
  orderBy('views', 'desc')
);

Firestore vous invite à créer l'index avec un lien direct lorsque vous exécutez cette requête.

3. Opérations par lots

import { writeBatch } from 'firebase/firestore';

async function bulkUpdate(userIds, updates) {
  const batch = writeBatch(db);

  userIds.forEach(id => {
    const ref = doc(db, 'users', id);
    batch.update(ref, updates);
  });

  await batch.commit();
  console.log(`Mis à jour ${userIds.length} utilisateurs`);
}

// Maximum 500 opérations par lot

4. Surveiller les coûts

Tarification Firebase :

Service Tier gratuit Payant
Firestore 50K lectures/jour 0,036 $/100K lectures
Stockage 5 Go 0,023 $/Go
Fonctions 2M invocations 0,40 $/1M
Authentification 10K/mois 0,0055 $/100K

Définissez des alertes budgétaires dans la console Google Cloud.

5. Sécuriser les comptes de service

// FAUX : Ne jamais faire cela dans le code client
admin.initializeApp({
  credential: admin.credential.cert(require('./serviceAccountKey.json'))
});

// CORRECT : Utiliser uniquement dans un environnement serveur
const serviceAccount = JSON.parse(process.env.FIREBASE_SERVICE_ACCOUNT);
admin.initializeApp({
  credential: admin.credential.cert(serviceAccount)
});

6. Gérer les scénarios hors ligne

// Activer la persistance hors ligne (web)
import { enableMultiTabIndexedDbPersistence } from 'firebase/firestore';

enableMultiTabIndexedDbPersistence(db)
  .catch((err) => {
    if (err.code === 'failed-precondition') {
      // Plusieurs onglets ouverts
    } else if (err.code === 'unimplemented') {
      // Le navigateur ne prend pas en charge
    }
  });

// Écouter la connectivité
import { onSnapshot } from 'firebase/firestore';

onSnapshot(doc(db, 'status', 'online'), (doc) => {
  if (!doc.exists()) {
    console.log('Vous êtes hors ligne');
    // Afficher l'interface utilisateur hors ligne
  }
});

Problèmes et solutions courants de l'API Firebase

Problème 1 : Erreurs d'autorisation refusée

Symptôme : Erreur : 7 PERMISSION_DENIED

Cause : Les règles de sécurité bloquent l'opération

Correction :

  1. Vérifiez les règles dans la console Firebase
  2. Vérifiez que request.auth.uid correspond à l'utilisateur attendu
  3. Testez les règles avec le Playground de règles

Problème 2 : Expiration du jeton

Symptôme : Erreur : Jeton d'ID expiré

Correction :

// Forcer le rafraîchissement du jeton
const user = auth.currentUser;
if (user) {
  await user.getIdToken(true); // Forcer le rafraîchissement
}

Problème 3 : Latence de démarrage à froid

Symptôme : Les fonctions Cloud prennent 2 à 5 secondes lors du premier appel

Correction :

// Garder les fonctions "chaudes" avec des pings planifiés
exports.keepWarm = onSchedule('toutes les 60 secondes', async () => {
  await fetch('https://votre-fonction.cloudfunctions.net/health');
});

Problème 4 : La requête renvoie des résultats vides

Symptôme : La requête devrait renvoyer des données mais renvoie un tableau vide

Cause : Index manquant ou ordre des champs incorrect

Correction : Vérifiez la console Firestore > Index pour les index composites requis.

Cas d'utilisation réels

Application Fintech : Mises à jour de transactions en temps réel

Une startup de paiement a utilisé Firebase Firestore pour créer des notifications de transactions en temps réel. Lorsqu'un paiement est traité, les fonctions Cloud déclenchent des mises à jour sur tous les tableaux de bord d'administration connectés en moins de 200 ms. Résultat : une réduction de 40 % des tickets de support concernant les transactions "en attente".

E-commerce : Synchronisation des stocks

Un détaillant en ligne synchronise son inventaire sur le web, iOS et Android à l'aide des écouteurs Firestore. Lorsque le stock change, tous les clients sont mis à jour automatiquement. La persistance hors ligne garantit que les employés de l'entrepôt peuvent scanner des articles sans connectivité, avec une synchronisation automatique une fois reconnectés.

SaaS : Authentification multi-locataires

Une plateforme B2B utilise Firebase Auth avec des revendications personnalisées pour l'accès basé sur les rôles. Les utilisateurs administrateurs obtiennent des autorisations élevées via des fonctions Cloud qui valident les configurations de locataires Firestore. Une seule base de code sert plus de 500 organisations avec des données isolées.

Conclusion

L'intégration de l'API Firebase implique quatre services principaux :

Vous avez appris les flux d'authentification, les opérations de base de données, le déploiement de fonctions et la gestion de fichiers. Vous avez vu des modèles de production : gestion des erreurs, traitement par lots, support hors ligne et sécurité.

bouton

FAQ

Firebase est-il gratuit ?

Oui, Firebase propose un niveau gratuit généreux (plan Spark) incluant 5 Go de stockage, 50K lectures Firestore/jour, 2M invocations de fonctions Cloud et 10K utilisateurs Auth/mois. Les plans payants (Blaze) utilisent une tarification à l'usage.

Puis-je utiliser Firebase avec des bases de données existantes ?

Oui. Utilisez les extensions Firebase pour synchroniser avec PostgreSQL, MySQL ou MongoDB. Ou appelez des API externes depuis les fonctions Cloud pour vous intégrer à des systèmes existants.

Comment migrer de Firebase vers une autre plateforme ?

Exportez les données à l'aide des fonctions d'exportation Firestore ou de la CLI Firebase. Pour les grands ensembles de données, utilisez le pipeline d'exportation Dataflow. La complexité de la migration dépend de la structure de vos données.

Firebase prend-il en charge GraphQL ?

Pas nativement. Utilisez des solutions tierces comme firestore-graphql ou construisez une couche GraphQL avec Cloud Functions et Apollo Server.

Puis-je utiliser Firebase sur site ?

Non. Firebase est exclusivement sur Google Cloud. Pour des alternatives auto-hébergées, envisagez Appwrite, Supabase ou Nhost.

Comment gérer les téléchargements de fichiers de plus de 100 Mo ?

Utilisez les téléchargements reprenables avec découpage (chunking). Le SDK Firebase gère cela automatiquement. Pour les fichiers très volumineux, utilisez directement Google Cloud Storage avec des URL signées.

Que se passe-t-il si je dépasse les limites de requêtes Firestore ?

Les requêtes échouent avec l'erreur FAILED_PRECONDITION. Ajoutez les index requis ou restructurez les requêtes. Firestore fournit des liens directs pour créer les index manquants dans le message d'erreur.

Firebase est-il conforme au RGPD ?

Oui, Firebase offre un traitement des données conforme au RGPD. Activez la résidence des données dans des régions spécifiques, implémentez l'exportation/suppression des données utilisateur et signez l'avenant relatif au traitement des données de Google.

Pratiquez le Design-first d'API dans Apidog

Découvrez une manière plus simple de créer et utiliser des API