Aller au contenu principal

📦 5.2A – firebase_firestore_setup

Objectif 🎯​

Apprendre à structurer et gérer des données avec Firestore (la base de données NoSQL orientée documents de Firebase).

À faire 🛠️​

Prérequis​

Avoir complété la configuration Firebase de base avec firebase_core et google_sign_in.

Étape 1 - Installation de cloud_firestore​

Valider que la librairie cliente est installée.

flutter pub add cloud_firestore
flutterfire configure

Configurez l'émulateur pour Firestore. La recette pour les émulateurs est disponible ici.

astuce

Si flutterfire configure ne trouve pas votre projet, suivez les instructions de Firebase kaputt đź§Ż.

Il devrait fonctionner au prochain cours 🙏🙏🙏.

Faites un COMMIT + PUSH.

Étape 2 - Tester l'accès à Firestore​

Pour vérifier que tout fonctionne correctement:

  • Quelque part dans votre application, ajoutez un bouton
  • Avec le code suivant
  • Quand on cliquera dessus cela devrait crĂ©er une entrĂ©e
MaterialButton(
onPressed: () {
final db = FirebaseFirestore.instance;
final user = <String, dynamic>{
"first": "Ada",
"last": "Lovelace",
"born": 1815,
};
db
.collection("users")
.add(user)
.then(
(DocumentReference doc) =>
print('DocumentSnapshot added with ID: ${doc.id}'),
);
},
child: const Text("Test ajout firestore"),
),
  • Lancez l'application
  • Appuyez sur le bouton créé
  • Allez Ă  la console Firebase dans le volet Firestore
  • Vous devriez voir les donnĂ©es apparaĂ®tre!

COMMIT et PUSH.

Étape 3 - Comprendre la structure Firestore​

Firestore est orienté documents, pas relationnel comme SQL:

  • Collections: Conteneurs de documents (comme des tables)
  • Documents: Objets JSON avec un ID unique
  • Subcollections: Collections imbriquĂ©es dans un document
  • Champs: PropriĂ©tĂ©s des documents

Exemple de structure:

users/
├── user1 (document)
│ ├── name: "Alice"
│ ├── email: "alice@example.com"
│ └── posts/ (subcollection)
│ ├── post1
│ └── post2
└── user2 (document)

Étape 4 - Créer une collection manuellement​

Dans la console Firestore:

  • Cliquez sur + CrĂ©er une collection
  • Nommez-la users
  • Cliquez sur Suivant
  • Cliquez sur Ajouter un document et remplissez manuellement:
    • ID: user1 (personnalisĂ©)
    • Champs:

Ajoutez quelques documents Ă  votre collection pour tester.

Étape 5 - Accéder aux données en Flutter​

Dans un StatefulWidget, créez une méthode pour récupérer les données:

Future<List<Map<String, dynamic>>> getUsers() async {
final db = FirebaseFirestore.instance;
final snapshot = await db.collection('users').get();

return snapshot.docs.map((doc) => doc.data()).toList();
}

Dans la UI, utilisez un FutureBuilder pour afficher les données:

FutureBuilder<List<Map<String, dynamic>>>(
future: getUsers(),
builder: (context, snapshot) {
if (snapshot.hasError) {
return Text('Erreur: ${snapshot.error}');
}

if (!snapshot.hasData) {
return Text('Chargement...');
}

final users = snapshot.data!;
return ListView.builder(
itemCount: users.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(users[index]['name']),
subtitle: Text(users[index]['email']),
);
},
);
},
)

Testez l'affichage de vos données.

Faites un COMMIT PUSH.

Étape 6 - Ajouter des données en Flutter​

Créez une méthode pour ajouter un nouvel utilisateur:

Future<void> addUser(String name, String email, int age) async {
final db = FirebaseFirestore.instance;

await db.collection('users').add({
'name': name,
'email': email,
'age': age,
});
}

Utilisez add() pour générer un ID automatiquement, ou set() si vous avez un ID spécifique:

await db.collection('users').doc('user123').set({
'name': 'Bob',
'email': 'bob@example.com',
});

Ajoutez un bouton pour insérer des données et vérifiez dans la console Firebase.

Faites un COMMIT PUSH.

Étape 7 - Utiliser StreamBuilder pour les mises à jour en temps réel​

Au lieu de récupérer les données une seule fois, utilisez snapshots() pour écouter les changements:

StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance.collection('users').snapshots(),
builder: (context, snapshot) {
if (snapshot.hasError) {
return Text('Erreur: ${snapshot.error}');
}

if (!snapshot.hasData) {
return Text('Chargement...');
}

final users = snapshot.data!.docs;
return ListView.builder(
itemCount: users.length,
itemBuilder: (context, index) {
final user = users[index].data() as Map<String, dynamic>;
return ListTile(
title: Text(user['name']),
subtitle: Text(user['email']),
);
},
);
},
)

Testez en ajoutant des documents dans la console Firebase — ils apparaîtront en temps réel!

Étape 8 - Mettre à jour et supprimer​

Pour mettre Ă  jour un document:

await db.collection('users').doc('user1').update({
'age': 26,
});

Pour supprimer un document:

await db.collection('users').doc('user1').delete();

Ajoutez des boutons pour tester ces opérations.

Faites un COMMIT PUSH.

Étape 9 - Filtrer et trier les données​

Vous pouvez filtrer les résultats avec where():

final query = db
.collection('users')
.where('age', isGreaterThan: 18)
.orderBy('age', descending: true);

final snapshot = await query.get();

Testez différentes requêtes pour comprendre le fonctionnement.

Étape 10 - Création d'une base de données Firestore​

Nous avons utilisé un émulateur, mais pour utiliser la vrai base de données Firebase :

  • Allez dans la console Firebase
  • SĂ©lectionnez votre projet
  • Dans le panneau Ă  gauche, cliquez sur Firestore Database
  • Cliquez sur CrĂ©er une base de donnĂ©es
  • SĂ©lectionnez le mode test (permet de lire/Ă©crire sans règles de sĂ©curitĂ©)
  • Continuez les Ă©tapes suivantes
  • Cliquez sur CrĂ©er

Projet récapitulatif​

Le projet qui intègre les éléments de ce laboratoire se retrouve ici.

Points clés à retenir​

  • âś… Firestore est NoSQL et orientĂ© documents
  • âś… Les collections sont flexibles (pas de schĂ©ma rigide)
  • âś… Utilisez StreamBuilder pour les mises Ă  jour en temps rĂ©el
  • âś… Chaque requĂŞte Ă  Firestore coĂ»te des "lectures" (attention aux quotas gratuits!)
  • âś… Structurez vos donnĂ©es intelligemment (denormalization vs sous-collections)