Initial commit: WalletTracker app with Firebase integration

- Setup Expo project with TypeScript
- Implement authentication (Login/Signup/Logout)
- Create Dashboard, Transactions, Subscriptions, and Analysis screens
- Add Firebase services (Auth, Firestore, Storage)
- Implement real-time synchronization
- Add charts and analytics
- Create reusable components (Button, InputText, TransactionCard, SubscriptionCard)
- Configure React Navigation with bottom tabs
- Add Firestore security rules
- Create comprehensive documentation (README, FIREBASE_SETUP, TESTING)
This commit is contained in:
2025-10-23 14:36:36 +02:00
parent c10b5ae013
commit 8bde3d4f21
26 changed files with 5622 additions and 17 deletions

92
firestore.rules Normal file
View File

@@ -0,0 +1,92 @@
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Fonction helper pour vérifier si l'utilisateur est authentifié
function isAuthenticated() {
return request.auth != null;
}
// Fonction helper pour vérifier si l'utilisateur est propriétaire
function isOwner(userId) {
return isAuthenticated() && request.auth.uid == userId;
}
// Règles pour la collection users
match /users/{userId} {
// Lecture : l'utilisateur peut lire ses propres données ou celles partagées avec lui
allow read: if isOwner(userId) ||
(isAuthenticated() &&
resource.data.sharedWith != null &&
request.auth.uid in resource.data.sharedWith);
// Écriture : uniquement le propriétaire
allow create: if isOwner(userId);
allow update: if isOwner(userId);
allow delete: if isOwner(userId);
}
// Règles pour la collection transactions
match /transactions/{transactionId} {
// Lecture : l'utilisateur peut lire ses propres transactions
allow read: if isAuthenticated() &&
resource.data.userId == request.auth.uid;
// Création : l'utilisateur peut créer ses propres transactions
allow create: if isAuthenticated() &&
request.resource.data.userId == request.auth.uid &&
request.resource.data.keys().hasAll(['userId', 'type', 'amount', 'category', 'date', 'createdAt', 'updatedAt']);
// Mise à jour : uniquement le propriétaire
allow update: if isAuthenticated() &&
resource.data.userId == request.auth.uid &&
request.resource.data.userId == resource.data.userId;
// Suppression : uniquement le propriétaire
allow delete: if isAuthenticated() &&
resource.data.userId == request.auth.uid;
}
// Règles pour la collection categories
match /categories/{categoryId} {
// Lecture : l'utilisateur peut lire ses propres catégories
allow read: if isAuthenticated() &&
resource.data.userId == request.auth.uid;
// Création : l'utilisateur peut créer ses propres catégories
allow create: if isAuthenticated() &&
request.resource.data.userId == request.auth.uid &&
request.resource.data.keys().hasAll(['userId', 'name', 'icon', 'color', 'type']);
// Mise à jour : uniquement le propriétaire
allow update: if isAuthenticated() &&
resource.data.userId == request.auth.uid &&
request.resource.data.userId == resource.data.userId;
// Suppression : uniquement le propriétaire
allow delete: if isAuthenticated() &&
resource.data.userId == request.auth.uid;
}
// Règles pour la collection subscriptions
match /subscriptions/{subscriptionId} {
// Lecture : l'utilisateur peut lire ses propres abonnements
allow read: if isAuthenticated() &&
resource.data.userId == request.auth.uid;
// Création : l'utilisateur peut créer ses propres abonnements
allow create: if isAuthenticated() &&
request.resource.data.userId == request.auth.uid &&
request.resource.data.keys().hasAll(['userId', 'name', 'amount', 'category', 'frequency', 'nextPaymentDate', 'reminderDaysBefore', 'isActive', 'createdAt', 'updatedAt']);
// Mise à jour : uniquement le propriétaire
allow update: if isAuthenticated() &&
resource.data.userId == request.auth.uid &&
request.resource.data.userId == resource.data.userId;
// Suppression : uniquement le propriétaire
allow delete: if isAuthenticated() &&
resource.data.userId == request.auth.uid;
}
}
}