Agent Skill
2/7/2026firebase-flutter
Firebase integration patterns for Flutter including Authentication, Cloud Firestore, and Storage. Use this skill when working with Firebase services, database queries, or authentication flows.
S
stormblessedf
0GitHub Stars
1Views
npx skills add stormblessedf/sportexd
SKILL.md
| Name | firebase-flutter |
| Description | Firebase integration patterns for Flutter including Authentication, Cloud Firestore, and Storage. Use this skill when working with Firebase services, database queries, or authentication flows. |
name: firebase-flutter description: Firebase integration patterns for Flutter including Authentication, Cloud Firestore, and Storage. Use this skill when working with Firebase services, database queries, or authentication flows.
Firebase Flutter Integration Skill
Firebase Authentication
Email/Password Sign Up
Future<UserCredential?> signUp(String email, String password) async {
try {
final credential = await FirebaseAuth.instance.createUserWithEmailAndPassword(
email: email,
password: password,
);
return credential;
} on FirebaseAuthException catch (e) {
// Handle specific error codes
switch (e.code) {
case 'weak-password':
throw 'Şifre çok zayıf';
case 'email-already-in-use':
throw 'Bu e-posta zaten kullanımda';
default:
throw 'Kayıt hatası: ${e.message}';
}
}
}
Email/Password Sign In
Future<UserCredential?> signIn(String email, String password) async {
try {
final credential = await FirebaseAuth.instance.signInWithEmailAndPassword(
email: email,
password: password,
);
return credential;
} on FirebaseAuthException catch (e) {
switch (e.code) {
case 'user-not-found':
throw 'Kullanıcı bulunamadı';
case 'wrong-password':
throw 'Yanlış şifre';
default:
throw 'Giriş hatası: ${e.message}';
}
}
}
Current User
// Get current user
final user = FirebaseAuth.instance.currentUser;
// Listen to auth state
FirebaseAuth.instance.authStateChanges().listen((User? user) {
if (user == null) {
// User is signed out
} else {
// User is signed in
}
});
Sign Out
await FirebaseAuth.instance.signOut();
Cloud Firestore
Document Operations
Create/Set Document
// With auto-generated ID
final docRef = await FirebaseFirestore.instance
.collection('users')
.add({'name': 'John', 'email': 'john@example.com'});
// With specific ID
await FirebaseFirestore.instance
.collection('users')
.doc(userId)
.set({'name': 'John', 'email': 'john@example.com'});
// Merge with existing
await FirebaseFirestore.instance
.collection('users')
.doc(userId)
.set({'name': 'John'}, SetOptions(merge: true));
Read Document
// Single read
final doc = await FirebaseFirestore.instance
.collection('users')
.doc(userId)
.get();
if (doc.exists) {
final data = doc.data()!;
return UserModel.fromMap(data, doc.id);
}
Update Document
await FirebaseFirestore.instance
.collection('users')
.doc(userId)
.update({
'name': 'New Name',
'updatedAt': FieldValue.serverTimestamp(),
});
Delete Document
await FirebaseFirestore.instance
.collection('users')
.doc(userId)
.delete();
Collection Queries
Basic Query
final snapshot = await FirebaseFirestore.instance
.collection('meetups')
.where('type', isEqualTo: 'football')
.orderBy('date', descending: true)
.limit(20)
.get();
final meetups = snapshot.docs
.map((doc) => MeetupModel.fromMap(doc.data(), doc.id))
.toList();
Stream Query (Real-time)
Stream<List<MeetupModel>> getMeetupsStream() {
return FirebaseFirestore.instance
.collection('meetups')
.orderBy('date', descending: true)
.snapshots()
.map((snapshot) => snapshot.docs
.map((doc) => MeetupModel.fromMap(doc.data(), doc.id))
.toList());
}
Compound Queries
// Multiple conditions
final snapshot = await FirebaseFirestore.instance
.collection('meetups')
.where('type', isEqualTo: 'football')
.where('date', isGreaterThan: DateTime.now())
.where('isFull', isEqualTo: false)
.get();
// Array contains
final snapshot = await FirebaseFirestore.instance
.collection('meetups')
.where('participantIds', arrayContains: userId)
.get();
Subcollections
// Add to subcollection
await FirebaseFirestore.instance
.collection('chats')
.doc(chatId)
.collection('messages')
.add({
'text': message,
'senderId': userId,
'timestamp': FieldValue.serverTimestamp(),
});
// Query subcollection
final messages = FirebaseFirestore.instance
.collection('chats')
.doc(chatId)
.collection('messages')
.orderBy('timestamp', descending: true)
.snapshots();
Transactions
await FirebaseFirestore.instance.runTransaction((transaction) async {
final meetupRef = FirebaseFirestore.instance
.collection('meetups')
.doc(meetupId);
final snapshot = await transaction.get(meetupRef);
final currentCount = snapshot.data()!['currentParticipants'] as int;
final maxCount = snapshot.data()!['maxParticipants'] as int;
if (currentCount >= maxCount) {
throw 'Meetup is full';
}
transaction.update(meetupRef, {
'currentParticipants': currentCount + 1,
'participantIds': FieldValue.arrayUnion([userId]),
});
});
Batch Writes
final batch = FirebaseFirestore.instance.batch();
batch.set(doc1Ref, data1);
batch.update(doc2Ref, data2);
batch.delete(doc3Ref);
await batch.commit();
Firebase Storage
Upload File
Future<String> uploadImage(File file, String path) async {
final ref = FirebaseStorage.instance.ref().child(path);
final uploadTask = ref.putFile(file);
final snapshot = await uploadTask.whenComplete(() {});
final downloadUrl = await snapshot.ref.getDownloadURL();
return downloadUrl;
}
Upload with Progress
final uploadTask = ref.putFile(file);
uploadTask.snapshotEvents.listen((TaskSnapshot snapshot) {
final progress = snapshot.bytesTransferred / snapshot.totalBytes;
print('Upload progress: ${(progress * 100).toStringAsFixed(0)}%');
});
await uploadTask.whenComplete(() {});
Delete File
await FirebaseStorage.instance.ref().child(path).delete();
Model Pattern
FromMap / ToMap
class UserModel {
final String id;
final String name;
final String email;
final DateTime? createdAt;
UserModel({
required this.id,
required this.name,
required this.email,
this.createdAt,
});
factory UserModel.fromMap(Map<String, dynamic> map, String id) {
return UserModel(
id: id,
name: map['name'] ?? '',
email: map['email'] ?? '',
createdAt: (map['createdAt'] as Timestamp?)?.toDate(),
);
}
Map<String, dynamic> toMap() {
return {
'name': name,
'email': email,
'createdAt': createdAt != null
? Timestamp.fromDate(createdAt!)
: FieldValue.serverTimestamp(),
};
}
UserModel copyWith({
String? name,
String? email,
}) {
return UserModel(
id: id,
name: name ?? this.name,
email: email ?? this.email,
createdAt: createdAt,
);
}
}
Security Rules Reference
Firestore Rules
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Users can read/write their own data
match /users/{userId} {
allow read: if request.auth != null;
allow write: if request.auth.uid == userId;
}
// Meetups readable by all authenticated users
match /meetups/{meetupId} {
allow read: if request.auth != null;
allow create: if request.auth != null;
allow update, delete: if request.auth.uid == resource.data.organizerId;
}
}
}
Guidelines
- Always handle FirebaseException with user-friendly messages
- Use transactions for operations that need atomicity
- Use FieldValue.serverTimestamp() for consistent timestamps
- Create indexes for compound queries in Firebase Console
- Use streams for real-time data, futures for one-time reads
- Store only necessary data - avoid deeply nested documents
- Use subcollections for large or frequently accessed related data
Skills Info
Original Name:firebase-flutterAuthor:stormblessedf
Download