Flutter với Firebase
 · 3 min read
Cài đặt và Cấu hình
Thêm Dependencies
dependencies:
  firebase_core: ^2.24.2
  firebase_auth: ^4.15.3
  cloud_firestore: ^4.13.6
  firebase_storage: ^11.5.6
Khởi tạo Firebase
void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );
  runApp(MyApp());
}
Authentication
Đăng ký người dùng
Future<UserCredential> signUpWithEmail(String email, String password) async {
  try {
    return await FirebaseAuth.instance.createUserWithEmailAndPassword(
      email: email,
      password: password,
    );
  } on FirebaseAuthException catch (e) {
    throw _handleAuthError(e);
  }
}
Đăng nhập
Future<UserCredential> signInWithEmail(String email, String password) async {
  try {
    return await FirebaseAuth.instance.signInWithEmailAndPassword(
      email: email,
      password: password,
    );
  } on FirebaseAuthException catch (e) {
    throw _handleAuthError(e);
  }
}
Cloud Firestore
CRUD Operations
// Thêm dữ liệu
Future<void> addUser(String userId, Map<String, dynamic> userData) async {
  await FirebaseFirestore.instance
      .collection('users')
      .doc(userId)
      .set(userData);
}
// Đọc dữ liệu
Future<DocumentSnapshot> getUser(String userId) async {
  return await FirebaseFirestore.instance
      .collection('users')
      .doc(userId)
      .get();
}
// Cập nhật dữ liệu
Future<void> updateUser(String userId, Map<String, dynamic> newData) async {
  await FirebaseFirestore.instance
      .collection('users')
      .doc(userId)
      .update(newData);
}
// Xóa dữ liệu
Future<void> deleteUser(String userId) async {
  await FirebaseFirestore.instance
      .collection('users')
      .doc(userId)
      .delete();
}
Realtime Updates
Stream<QuerySnapshot> getUsersStream() {
  return FirebaseFirestore.instance
      .collection('users')
      .snapshots();
}
// Sử dụng trong Widget
StreamBuilder<QuerySnapshot>(
  stream: getUsersStream(),
  builder: (context, snapshot) {
    if (snapshot.hasError) {
      return Text('Có lỗi xảy ra');
    }
    if (snapshot.connectionState == ConnectionState.waiting) {
      return CircularProgressIndicator();
    }
    return ListView(
      children: snapshot.data!.docs.map((doc) {
        return ListTile(
          title: Text(doc['name']),
        );
      }).toList(),
    );
  },
)
Cloud Storage
Upload Files
Future<String> uploadFile(File file, String path) async {
  try {
    final ref = FirebaseStorage.instance.ref().child(path);
    final uploadTask = ref.putFile(file);
    final snapshot = await uploadTask.whenComplete(() {});
    return await snapshot.ref.getDownloadURL();
  } catch (e) {
    throw Exception('Lỗi khi upload file: $e');
  }
}
Download Files
Future<void> downloadFile(String url, String localPath) async {
  try {
    final ref = FirebaseStorage.instance.refFromURL(url);
    final file = File(localPath);
    await ref.writeToFile(file);
  } catch (e) {
    throw Exception('Lỗi khi download file: $e');
  }
}
Security Rules
Firestore Rules
rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{userId} {
      allow read: if request.auth != null;
      allow write: if request.auth.uid == userId;
    }
  }
}
Storage Rules
rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read: if request.auth != null;
      allow write: if request.auth != null;
    }
  }
}
Best Practices
Authentication
- Luôn xử lý lỗi authentication
- Sử dụng các phương thức bảo mật như email verification
- Implement proper session management
Database
- Cấu trúc dữ liệu phù hợp
- Sử dụng indexes cho queries phức tạp
- Implement caching cho offline support
Storage
- Validate file size và type trước khi upload
- Implement progress monitoring cho large files
- Sử dụng compression khi cần thiết
