Skip to content

🔴 Problème Firestore - Explication Complète

📋 Résumé du Problème

L'application affiche une erreur "permission denied" lors du démarrage en production, mais fonctionne correctement en développement avec flutter install.

Erreur exacte:

[cloud_firestore/permission-denied] The caller does not have permission 
to execute the specified operation.


🔍 Cause Racine Identifiée

Historique du Changement

Le 2 novembre 2025, un commit a modifié le fichier firebase_service.dart :

Commit: 06af1c3 - "Utilisation d'une vraie table que test_connection"

Changement effectué:

// AVANT (fonctionnait)
final result = await FirebaseFirestore.instance
    .collection('test_connection')  // ← Collection de test
    .limit(1)
    .get(...)

// APRÈS (ne fonctionne plus)
final result = await FirebaseFirestore.instance
    .collection(tableAppUsers)  // ← Collection 'app_users'
    .limit(1)
    .get(...)

Pourquoi Cela Cause un Problème ?

Collection test_connection (Avant)

  • ❌ N'existait pas
  • ✅ Mais n'avait pas de règles restrictives
  • ✅ Firestore retournait une erreur "collection not found" mais pas "permission denied"

Collection app_users (Après)

  • ✅ Existe vraiment
  • A des règles restrictives :
match /app_users/{userId} {
  allow read, write, delete: if request.auth != null && request.auth.uid == userId;
}

La règle exige: request.auth != null (l'utilisateur doit être authentifié)

Le Flux Problématique

1. Application démarre
   ↓
2. main.dart appelle _initFirebase()
   ↓
3. firebase_service.dart → initializeFirebase()
   ↓
4. checkFirestoreConnection() essaie de lire app_users
   ↓
5. ❌ ERREUR: request.auth est NULL (pas d'authentification encore)
   ↓
6. Firestore refuse l'accès: "permission-denied"
   ↓
7. L'application crash

🎯 Pourquoi Cela Fonctionne en Développement ?

Avec flutter install, l'application utilise la clé de signature debug qui est configurée différemment dans Firebase. Cependant, le vrai problème est que :

  1. En développement, vous testez probablement sur un émulateur ou un téléphone connecté
  2. Les règles Firestore peuvent être en mode "test" (moins restrictives)
  3. Ou vous êtes déjà authentifié lors du test

En production (Play Store), les règles sont strictes et l'utilisateur n'est pas authentifié au démarrage.


✅ Solutions Possibles

Solution 1 (Recommandée): Utiliser foods au lieu de app_users

Pourquoi ? - La collection foods a une règle publique : allow read: if true; - Elle existe et contient des données - C'est le bon choix pour vérifier la connexion Firestore

Modification dans firebase_service.dart (ligne ~141):

// AVANT
final result = await FirebaseFirestore.instance
    .collection(tableAppUsers)  // ❌ Nécessite authentification
    .limit(1)
    .get(...)

// APRÈS
final result = await FirebaseFirestore.instance
    .collection(tableFoods)  // ✅ Publique
    .limit(1)
    .get(...)

Avantages: - ✅ Sécurisé (ne change pas les règles) - ✅ Simple (une ligne à changer) - ✅ Logique (vérifier une collection publique)

Inconvénients: - ❌ Dépend de l'existence de données dans foods


Solution 2: Modifier les Règles Firestore

Autoriser la lecture publique à app_users :

match /app_users/{userId} {
  allow read: if true;  // ✅ Lecture publique pour l'initialisation
  allow write, delete: if request.auth != null && request.auth.uid == userId;
}

Avantages: - ✅ Fonctionne même sans données dans foods - ✅ Plus flexible

Inconvénients: - ❌ Moins sécurisé (expose les données utilisateur) - ❌ Nécessite une modification des règles Firestore


Solution 3: Créer une Collection de Test Publique

Créer une collection test_connection avec des règles publiques :

match /test_connection/{document=**} {
  allow read, write: if true;
}

Et garder le code actuel.

Avantages: - ✅ Dédié au test de connexion - ✅ Clair et explicite

Inconvénients: - ❌ Ajoute une collection inutile - ❌ Nécessite une modification des règles Firestore


🏆 Recommandation Finale

Utilisez la Solution 1 : Changer tableAppUsers en tableFoods

Raison : C'est la plus simple, la plus sécurisée et la plus logique.

Étapes à Faire

  1. Ouvrir lib/services/firebase_service.dart
  2. Trouver la ligne ~141 (dans checkFirestoreConnection())
  3. Remplacer tableAppUsers par tableFoods (2 occurrences)
  4. Sauvegarder
  5. Reconstruire l'APK : flutter build apk --release
  6. Tester

📊 Comparaison des Solutions

Critère Solution 1 Solution 2 Solution 3
Sécurité ✅ Excellente ⚠️ Moyenne ✅ Bonne
Simplicité ✅ Très simple ⚠️ Moyenne ⚠️ Moyenne
Dépendances ⚠️ Nécessite foods ✅ Aucune ✅ Aucune
Temps ✅ 5 minutes ⚠️ 10 minutes ⚠️ 10 minutes
Recommandé ✅ OUI ❌ Non ❌ Non

🔧 Code à Modifier

Fichier: lib/services/firebase_service.dart

Cherchez cette section (autour de la ligne 141):

// Tente de récupérer un document avec gestion du cache
final result = await FirebaseFirestore.instance
    .collection(tableAppUsers)  // ← À CHANGER
    .limit(1)
    .get(
      GetOptions(
        source: useCache ? Source.serverAndCache : Source.server,
      ),
    )

Remplacez par:

// Tente de récupérer un document avec gestion du cache
final result = await FirebaseFirestore.instance
    .collection(tableFoods)  // ← CHANGÉ
    .limit(1)
    .get(
      GetOptions(
        source: useCache ? Source.serverAndCache : Source.server,
      ),
    )

Et aussi (autour de la ligne 155):

// AVANT
return FirebaseFirestore.instance
    .collection(tableAppUsers)  // ← À CHANGER
    .limit(1)
    .get(const GetOptions(source: Source.cache));

// APRÈS
return FirebaseFirestore.instance
    .collection(tableFoods)  // ← CHANGÉ
    .limit(1)
    .get(const GetOptions(source: Source.cache));

🧪 Vérification Après Correction

# 1. Nettoyer
flutter clean

# 2. Reconstruire
flutter build apk --release

# 3. Installer
flutter install

# 4. Vérifier les logs
adb logcat -d | grep -i "firestore\|permission"

Résultat attendu:

✅ Connexion Firestore établie avec succès

Au lieu de:

❌ [cloud_firestore/permission-denied]


📝 Résumé

Point Détail
Problème Collection app_users nécessite authentification
Cause Commit du 2 nov qui a changé test_connection en app_users
Solution Utiliser foods à la place (collection publique)
Effort 5 minutes
Risque Très faible

❓ Questions Fréquentes

Q: Pourquoi cela fonctionne en développement ? A: Probablement parce que vous êtes déjà authentifié ou que les règles sont en mode test.

Q: Cela affecte la sécurité ? A: Non, foods est déjà publique de toute façon.

Q: Faut-il reconstruire l'APK ? A: Oui, car c'est une modification du code, pas des règles Firestore.

Q: Cela va-t-il casser quelque chose ? A: Non, c'est juste pour vérifier la connexion au démarrage.


📞 Support

Si vous avez des questions ou des problèmes après la correction, vérifiez: 1. Les logs: adb logcat -d | grep flutter 2. Que foods contient des données 3. Que les règles Firestore sont correctes