Firebase Firestore est une base de données NoSQL cloud en temps réel de Google, conçue pour les applications mobiles et web. Elle stocke les données dans des collections et des documents avec une synchronisation automatique entre les clients. Selon la documentation Firebase, 2025, Firestore prend en charge le déploiement multirégional avec une cohérence forte et assure une mise à l'échelle automatique sans nécessité de gérer les serveurs. La base de données s'intègre avec Firebase Authentication et Cloud Functions pour construire un backend complet sans infrastructure serveur propre.
Points clés
Firebase Firestore est une base de données NoSQL flexible et évolutive lancée par Google en 2019 comme évolution de Firebase Realtime Database. Elle stocke les données dans des collections de documents, où chaque document contient un ensemble de paires clé-valeur. Contrairement aux bases de données relationnelles traditionnelles, Firestore ne nécessite pas de schéma prédéfini — la structure des données se forme dynamiquement en fonction des documents écrits.
La principale différence entre Firestore et les bases de données cloud classiques est la synchronisation intégrée en temps réel. Lorsque les données changent sur le serveur, tous les clients connectés reçoivent les mises à jour via une connexion WebSocket persistante. Cela élimine le besoin d'interrogation manuelle du serveur et permet de construire des applications avec des mises à jour en direct : chats, flux d'activité, éditeurs collaboratifs et systèmes de surveillance.
La base de données est disponible sur toutes les principales plateformes : Android, iOS, Web (JavaScript) et langages serveur via Admin SDK. Firestore fournit un SDK pour Swift, Kotlin, JavaScript, Python, Go, Java et Node.js. Selon Google, Firestore traite plus de 100 milliards de requêtes par jour dans tout l'écosystème Firebase, confirmant sa fiabilité comme base pour les applications de production.
Dans Firestore, les données sont organisées dans une structure hiérarchique. Une collection est un conteneur de documents, similaire à une table en SQL mais sans schéma fixe. Un document est un enregistrement contenant des champs de différents types : chaînes, nombres, valeurs booléennes, tableaux, objets imbriqués et géopoints. Les documents peuvent contenir des sous-collections, permettant de construire des structures de données imbriquées de n'importe quelle profondeur.
val db = FirebaseFirestore.getInstance()
val user = hashMapOf(
"name" to "Anna Petrova",
"email" to "anna@example.com",
"age" to 28,
"isActive" to true
)
db.collection("users")
.add(user)
.addOnSuccessListener { docRef ->
Log.d("TAG", "Document ajouté avec l'ID : ${docRef.id}")
}
Chaque document dans une collection a un identifiant unique, qui peut être généré automatiquement ou défini manuellement. Firestore indexe automatiquement tous les champs du document, permettant des requêtes complexes avec filtrage, tri et limitation des résultats sans configuration manuelle des index.
Firestore et Firebase Realtime Database sont deux bases de données cloud en temps réel de Google. Bien que toutes deux offrent une synchronisation en temps réel, elles présentent des différences fondamentales dans le modèle de données, la mise à l'échelle et la tarification. Comprendre ces différences est crucial lors du choix de la base de données appropriée pour un projet spécifique.
| Caractéristique | Firestore | Realtime Database |
|---|---|---|
| Modèle de données | Collections et documents | Arbre JSON unique |
| Cohérence | Cohérence forte | Cohérence éventuelle |
| Requêtes | Composées avec filtrage et tri | Filtrage par un seul paramètre |
| Mise à l'échelle | Automatique, multirégionale | Région unique, jusqu'à 200k connexions |
| Tarification | Par opérations de lecture/écriture/suppression | Par volume de données transférées |
La principale différence architecturale est le modèle de données. Realtime Database stocke tout dans un grand arbre JSON, ce qui complique les requêtes avec des imbrications profondes. Firestore utilise des collections et des documents, permettant des requêtes complexes avec plusieurs conditions. De plus, Firestore assure une cohérence forte des données : après une écriture réussie, toutes les lectures suivantes garantissent de retourner les données les plus récentes.
Firestore évolue automatiquement jusqu'à des millions de connexions simultanées grâce à son architecture multirégionale. Realtime Database est limitée à une seule région et un maximum de 200 000 connexions simultanées. Pour les projets visant un public mondial, Firestore est préférable car les données sont automatiquement répliquées entre plusieurs centres de données Google.
La structure de données dans Firestore permet de construire des modèles hiérarchiques complexes avec des sous-collections. Par exemple, un utilisateur peut avoir une sous-collection « commandes », et chaque commande une sous-collection « articles ». Dans Realtime Database, un tel imbrication profonde entraîne des problèmes de performances lors des requêtes, car tout le chemin de la racine au nœud nécessaire est chargé.
Firestore utilise une connexion WebSocket persistante entre le client et le serveur pour la synchronisation des données en temps réel. Lorsqu'une application s'abonne aux modifications d'un document ou d'une collection via un écouteur d'instantané, le SDK établit un canal de communication par lequel le serveur envoie des mises à jour à chaque modification des données. Le client reçoit uniquement les documents modifiés, pas un instantané complet de toute la collection à chaque fois.
Le mécanisme de synchronisation est basé sur un flux d'événements : added (document apparu), modified (document modifié) et removed (document supprimé). Le développeur peut traiter chaque événement séparément, en mettant à jour uniquement les éléments d'interface correspondants. Cela garantit des performances élevées même avec des milliers de documents, car seuls les composants modifiés sont rendus à nouveau.
L'un des principaux avantages de Firestore est la prise en charge intégrée du mode hors ligne. Le SDK met automatiquement en cache toutes les données lues sur l'appareil et continue de fonctionner en l'absence de réseau. Lorsque l'application écrit des données en mode hors ligne, elles sont placées dans une file d'attente locale et envoyées au serveur lors de la restauration de la connexion. La stratégie last-write-wins est utilisée pour la résolution des conflits.
val docRef = db.collection("cities").document("SF")
docRef.addSnapshotListener { snapshot, error ->
if (error != null) {
Log.w("TAG", "Erreur d'écoute", error)
return@addSnapshotListener
}
if (snapshot != null && snapshot.exists()) {
Log.d("TAG", "Données actuelles : ${snapshot.data}")
}
}
La taille du cache peut être configurée via FirestoreSettings. La valeur par défaut est de 100 Mo, mais elle peut être augmentée pour les applications avec une lecture intensive des données. Un mode de cache disque persistant est également disponible, qui survit aux redémarrages de l'application. Pour gérer la disponibilité du mode hors ligne, les méthodes enableNetwork et disableNetwork sont utilisées, permettant de désactiver temporairement l'interaction réseau.
Firestore Security Rules est un langage de balisage déclaratif pour contrôler l'accès aux données au niveau du serveur. Les règles définissent qui peut lire et écrire des documents et sous quelles conditions. Elles fonctionnent avant l'exécution de la requête et ne nécessitent pas de logique serveur distincte pour l'autorisation. Les règles sont vérifiées côté Firebase avant chaque lecture ou écriture de données.
Les règles d'accès sont construites sur le principe d'autorisation (allow). Par défaut, tout accès est refusé. Le développeur ouvre séquentiellement l'accès pour des opérations spécifiques (read, write, create, update, delete) sous certaines conditions. Les conditions peuvent vérifier l'authentification de l'utilisateur via request.auth, les données de la requête via request.resource et les données existantes via resource.
// Règles d'accès Firestore
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// L'utilisateur lit et écrit seulement ses propres données
match /users/{userId} {
allow read, write: if
request.auth != null &&
request.auth.uid == userId;
}
// Tout utilisateur authentifié peut lire les publications
match /posts/{postId} {
allow read: if request.auth != null;
allow create: if request.auth != null
&& request.resource.data.author == request.auth.uid;
}
}
}
En plus du contrôle d'accès, les Security Rules permettent de valider la structure et les types des données écrites. Par exemple, on peut vérifier que le champ email correspond à une expression régulière, ou que l'âge ne dépasse pas 120 ans. La validation est effectuée avant l'écriture, empêchant l'enregistrement de données incorrectes sur le serveur. Pour la validation des champs, l'objet request.resource.data est utilisé, contenant le document complet en cours d'écriture.
Firestore prend également en charge les collections accessibles uniquement en écriture côté serveur via Admin SDK, sans accès client. Cela est pratique pour stocker des informations de service, des clés API et des configurations qui ne doivent pas être visibles par les utilisateurs. Pour ce faire, il suffit de refuser toutes les opérations client sur les collections correspondantes dans les règles, en autorisant l'accès uniquement via Admin SDK côté serveur.
Examinons un exemple d'intégration de Firestore dans une application Android pour créer une liste de tâches (todo). L'application lira les tâches en temps réel, en ajoutera de nouvelles et marquera les tâches terminées. Pour le travail asynchrone, les interfaces de rappel Firebase et les coroutines Kotlin sont utilisées.
Avant de commencer, il est nécessaire de connecter le projet à Firebase via Firebase Console et d'ajouter le fichier google-services.json au module d'application. Ensuite, dans build.gradle, on ajoute la dépendance firebase-firestore-ktx et le plugin google-services. La version de la bibliothèque doit correspondre à la version actuelle de BoM Firebase pour la compatibilité de tous les composants Firebase entre eux.
dependencies {
// Firebase BoM — gestion des versions
implementation platform("com.google.firebase:firebase-bom:33.0.0")
implementation "com.google.firebase:firebase-firestore-ktx"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.9.0"
}
Après la configuration, un modèle de données Task et un dépôt pour travailler avec Firestore sont créés. Le modèle contient les champs id, title, isCompleted et timestamp. Firestore sérialise automatiquement la classe de données en un document, en utilisant les noms de champs comme clés. Pour lire les données, un écouteur d'instantané est utilisé, qui renvoie un Flow via l'extension snapshotFlow.
data class Task(
val id: String = "",
val title: String = "",
val isCompleted: Boolean = false,
val createdAt: Timestamp? = null
)
class TaskRepository {
private val tasksRef = FirebaseFirestore
.getInstance()
.collection("tasks")
fun getTasks(): Flow<List<Task>> = tasksRef
.orderBy("createdAt", Query.Direction.DESCENDING)
.snapshotFlow()
.map { snapshot ->
snapshot?.toObjects(Task::class.java) ?: emptyList()
}
suspend fun addTask(title: String) {
tasksRef.add(Task(title = title))
}
}
Le ViewModel s'abonne au Flow du dépôt et transmet la liste des tâches au niveau de l'interface utilisateur. Lors de l'ajout d'une nouvelle tâche, la fonction suspend du dépôt est appelée via une portée de coroutine. Firestore synchronise automatiquement les modifications entre tous les clients : si un utilisateur ajoute une tâche, les autres la voient en temps réel sans recharger l'écran.
Questions fréquentes
Firestore est une base de données NoSQL avec un schéma flexible, sans tables ni requêtes JOIN. Les données sont stockées dans des collections de documents, pas dans des lignes de tableaux. Contrairement à SQL, Firestore ne nécessite pas de schéma prédéfini et évolue automatiquement sans migrations, mais il ne prend pas en charge les requêtes transactionnelles complexes entre collections.
Firestore dispose d'une généreuse limite gratuite (plan Spark) : 50 000 lectures, 20 000 écritures et 20 000 suppressions par jour. Au-delà, le plan Blaze avec paiement à l'utilisation est appliqué : 0,06 $ pour 100 000 lectures et 0,18 $ pour 100 000 écritures. Le prix dépend de la région et du volume de données transférées.
Firestore utilise la stratégie last-write-wins pour résoudre les conflits : la dernière écriture sur un document remplace complètement la précédente. Pour un contrôle plus précis, des transactions (opérations atomiques de lecture-écriture) et des écritures par lots sont disponibles, garantissant l'intégrité lors des opérations sur plusieurs documents.
Oui, Firestore prend en charge l'exportation et l'importation de données via Firebase Console ou gcloud CLI. L'exportation est effectuée au format Cloud Firestore Export et sauvegardée dans Google Cloud Storage. Les données peuvent être migrées entre projets Firebase ou exportées pour analyse dans BigQuery et d'autres outils.
Firestore n'a pas de recherche en texte intégral intégrée. Pour cette tâche, Google recommande l'intégration avec Algolia ou Meilisearch, ou l'utilisation de Cloud Functions avec Elasticsearch. Les requêtes intégrées de Firestore ne prennent en charge que les vérifications d'égalité, de plage et d'existence de champ sans recherche par sous-chaîne.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi