Câu hỏi phỏng vấn Firebase 2026: Xác thực Flutter, Firestore và quy tắc bảo mật

Câu hỏi phỏng vấn Firebase cho lập trình viên Flutter, kèm câu trả lời bằng Dart: stream trạng thái xác thực, Google Sign-In v7, CRUD và mô hình hóa Firestore, quy tắc bảo mật, custom claims, transaction và các thay đổi của FlutterFire 5.

Tích hợp Flutter và Firebase minh họa kiến trúc xác thực và cơ sở dữ liệu Firestore

Câu hỏi phỏng vấn Firebase cho vị trí Flutter xoay quanh năm chủ đề: ba stream trạng thái xác thực, mô hình hóa dữ liệu Firestore, quy tắc bảo mật, ghi ngoại tuyến và mô hình chi phí đằng sau mỗi lần đọc. Firebase vẫn là backend mặc định cho ứng dụng Flutter năm 2026, và từ tháng 10/2026 các plugin FlutterFire được phát hành dưới dạng BoM 5.x (firebase_core 5.1.0, firebase_auth 7.0.1, cloud_firestore 7.1.0), với minSdk Android nâng lên 24 và Firebase Apple SDK 13 bên dưới.

FlutterFire BoM 5.1.0 (tháng 10/2026)

Bản phát hành FlutterFire hiện tại là BoM 5.1.0: firebase_auth 7.0.1, cloud_firestore 7.1.0, firebase_core 5.1.0. Phiên bản chính 5.0.0 yêu cầu minSdk Android 24, dựa trên Firebase Apple SDK 13.0.0 và đổi tên các tham số activate của App Check. Firestore Pipelines, được thêm vào từ cloud_firestore 6.3.0, tiếp tục có thêm biểu thức mới ở mỗi bản phát hành.

Câu Hỏi Phỏng Vấn Firebase: Những Gì Được Hỏi Năm 2026

Người phỏng vấn hiếm khi hỏi chi tiết API thuộc lòng. Họ kiểm tra xem ứng viên có hiểu Firebase áp dụng quy tắc ở đâu, mỗi thao tác tốn bao nhiêu và điều gì xảy ra khi mất mạng hay không. Bảng dưới đây liệt kê các chủ đề thường gặp cùng nội dung mà một câu trả lời tốt phải có. Mỗi chủ đề được giải đáp chi tiết trong phần câu hỏi phỏng vấn Firebase cho lập trình viên Flutter ở phía dưới.

Chủ đềCâu hỏi điển hìnhCâu trả lời tốt cần có
Stream authauthStateChanges() vs idTokenChanges() vs userChanges()Mỗi stream phát ra sự kiện nào, và stream nào dùng để bảo vệ điều hướng
Bảo mậtKiểm soát truy cập được áp dụng ở đâu?Quy tắc bảo mật trên máy chủ, không bao giờ là kiểm tra phía client; App Check là một lớp khác
Vai tròTriển khai vai trò admin như thế nào?Custom claims do Admin SDK thiết lập, đọc qua request.auth.token
Mô hình dữ liệuMô hình hóa một ứng dụng chatSubcollection, tin nhắn cuối được phi chuẩn hóa, mỗi tin nhắn một document
Tính nhất quánTransaction hay batched write?Transaction đọc rồi ghi và được thử lại; batch chỉ ghi, một cách nguyên tử
Ngoại tuyếnThao tác ghi khi ngoại tuyến sẽ ra sao?Cache cục bộ, hasPendingWrites, đồng bộ khi có kết nối lại
Chi phíVì sao màn hình này tốn kém?Tính phí theo mỗi lần đọc document, listener, phân trang bằng cursor
So sánhFirestore vs Realtime DatabaseMô hình truy vấn, khả năng mở rộng, đơn vị tính phí

Thiết Lập Firebase Trong Dự Án Flutter

Trước khi viết bất kỳ mã Firebase nào, dự án cần được khởi tạo đúng cách. FlutterFire CLI tự động đăng ký nền tảng và tạo các tệp cấu hình cho Android, iOS, web và macOS.

main.dartdart
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'firebase_options.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  // Initialize Firebase with platform-specific config
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );
  runApp(const MyApp());
}

Tệp firebase_options.dart được tạo tự động khi chạy flutterfire configure. Nó chứa khóa API, ID dự án và các định danh riêng cho từng nền tảng, nên không có gì phải sao chép thủ công từ Firebase console.

Firebase Authentication: Email, Google và Đa Yếu Tố

Firebase Authentication xử lý danh tính người dùng với mã soạn sẵn tối thiểu. Gói firebase_auth hỗ trợ email/mật khẩu, các nhà cung cấp OAuth (Google, Apple, GitHub), xác minh SMS qua điện thoại và xác thực đa yếu tố, bao gồm TOTP trên macOS kể từ firebase_auth 6.1.0.

Đăng Ký Bằng Email và Mật Khẩu

Luồng phổ biến nhất bắt đầu với email/mật khẩu. Phương thức createUserWithEmailAndPassword trả về một UserCredential chứa đối tượng User đã được xác thực.

auth_service.dartdart
import 'package:firebase_auth/firebase_auth.dart';

class AuthService {
  final FirebaseAuth _auth = FirebaseAuth.instance;

  // Register with email and password
  Future<User?> register(String email, String password) async {
    try {
      final credential = await _auth.createUserWithEmailAndPassword(
        email: email,
        password: password,
      );
      return credential.user;
    } on FirebaseAuthException catch (e) {
      // Handle specific error codes
      switch (e.code) {
        case 'email-already-in-use':
          throw Exception('This email is already registered');
        case 'weak-password':
          throw Exception('Password must be at least 6 characters');
        default:
          throw Exception('Registration failed: ${e.message}');
      }
    }
  }

  // Sign in with existing credentials
  Future<User?> signIn(String email, String password) async {
    final credential = await _auth.signInWithEmailAndPassword(
      email: email,
      password: password,
    );
    return credential.user;
  }

  // Reactive auth state stream
  Stream<User?> get authStateChanges => _auth.authStateChanges();
}

Stream authStateChanges() là cách được khuyến nghị để theo dõi trạng thái đăng nhập trên toàn ứng dụng. Nó phát ra User hiện tại khi đăng ký lắng nghe và kích hoạt lại trên mỗi sự kiện đăng nhập hoặc đăng xuất.

Quy tắc mật khẩu không còn phải nằm riêng ở phía client: API validatePassword (có từ firebase_auth 6.0.0) kiểm tra mật khẩu theo chính sách được cấu hình trong Firebase console, có thể yêu cầu độ dài tối thiểu, chữ hoa, chữ thường, chữ số và ký tự đặc biệt.

Tích Hợp Google Sign-In

Các nhà cung cấp OAuth cần thêm một gói riêng. Kể từ google_sign_in 7.0, plugin là một singleton lấy qua GoogleSignIn.instance, phải được khởi tạo đúng một lần, và xác thực được tách khỏi ủy quyền. Lệnh gọi GoogleSignIn().signIn() trong các hướng dẫn cũ không còn biên dịch được.

google_auth.dartdart
import 'package:firebase_auth/firebase_auth.dart';
import 'package:google_sign_in/google_sign_in.dart';

// Call once at startup, before any other GoogleSignIn method
Future<void> initGoogleSignIn() => GoogleSignIn.instance.initialize();

Future<UserCredential> signInWithGoogle() async {
  try {
    // Shows the native account picker; throws if the user cancels
    final googleUser = await GoogleSignIn.instance.authenticate();

    // Synchronous getter since v7: only the ID token is exposed here
    final googleAuth = googleUser.authentication;

    // Firebase only needs the ID token to create the credential
    final credential = GoogleAuthProvider.credential(
      idToken: googleAuth.idToken,
    );
    return FirebaseAuth.instance.signInWithCredential(credential);
  } on GoogleSignInException catch (e) {
    if (e.code == GoogleSignInExceptionCode.canceled) {
      throw Exception('Sign-in cancelled');
    }
    rethrow;
  }
}

Mẫu này áp dụng cho tất cả nhà cung cấp OAuth: lấy token của nhà cung cấp, bọc nó trong một credential Firebase, rồi gọi signInWithCredential. Khi ứng dụng cũng cần gọi một API của Google (Drive, Calendar), access token giờ đến từ một bước riêng, authorizationClient.authorizeScopes, như mô tả trong hướng dẫn di chuyển google_sign_in.

Bẫy Phỏng Vấn: Google Sign-In v7

Ứng viên viết GoogleSignIn().signIn() và đọc accessToken từ authentication đang dùng API trước bản 7.0. Ở v7, authenticate() trả về tài khoản, authentication chỉ chứa idToken, và access token cho các scope bổ sung cần một lệnh gọi ủy quyền tường minh.

Các Thao Tác CRUD Firestore và Mô Hình Hóa Dữ Liệu

Cloud Firestore tổ chức dữ liệu thành các collection và document. Không giống cơ sở dữ liệu SQL, Firestore không có schema: mỗi document có thể chứa các trường khác nhau. Sự linh hoạt này phù hợp với ứng dụng Flutter, nhưng đòi hỏi mô hình hóa dữ liệu kỷ luật để tránh các vấn đề về hiệu năng.

Ghi và Đọc Document

Các thao tác Firestore rất đơn giản với gói cloud_firestore. Mỗi lần đọc và ghi đều nhắm đến một đường dẫn document cụ thể.

firestore_service.dartdart
import 'package:cloud_firestore/cloud_firestore.dart';

class TaskService {
  final _db = FirebaseFirestore.instance;
  final String _collection = 'tasks';

  // Create a new document with auto-generated ID
  Future<String> createTask(String userId, String title) async {
    final doc = await _db.collection(_collection).add({
      'userId': userId,
      'title': title,
      'completed': false,
      'createdAt': FieldValue.serverTimestamp(),
    });
    return doc.id;
  }

  // Read a single document by ID
  Future<Map<String, dynamic>?> getTask(String taskId) async {
    final snapshot = await _db.collection(_collection).doc(taskId).get();
    return snapshot.data();
  }

  // Update specific fields without overwriting the entire document
  Future<void> toggleComplete(String taskId, bool completed) async {
    await _db.collection(_collection).doc(taskId).update({
      'completed': completed,
      'updatedAt': FieldValue.serverTimestamp(),
    });
  }

  // Delete a document
  Future<void> deleteTask(String taskId) async {
    await _db.collection(_collection).doc(taskId).delete();
  }
}

FieldValue.serverTimestamp() đảm bảo timestamp nhất quán trên mọi thiết bị bằng cách dùng đồng hồ máy chủ Firestore thay vì đồng hồ máy khách. Kể từ cloud_firestore 7.1.0, FieldValue.minimum và FieldValue.maximum được bổ sung vào nhóm biến đổi phía máy chủ: chúng giữ giá trị nhỏ hơn hoặc lớn hơn giữa giá trị đã lưu và giá trị gửi lên mà không cần đọc, phù hợp với các bộ đếm như điểm cao nhất.

Stream Thời Gian Thực Với snapshots()

Firestore tỏa sáng với đồng bộ hóa thời gian thực. Phương thức snapshots() trả về một Stream phát ra dữ liệu mới mỗi khi các document bên dưới thay đổi, không cần polling.

real_time_tasks.dartdart
import 'package:cloud_firestore/cloud_firestore.dart';

class TaskStream {
  final _db = FirebaseFirestore.instance;

  // Stream all tasks for a specific user, ordered by creation date
  Stream<List<Map<String, dynamic>>> userTasks(String userId) {
    return _db
        .collection('tasks')
        .where('userId', isEqualTo: userId)
        .orderBy('createdAt', descending: true)
        .snapshots()
        .map((snapshot) => snapshot.docs.map((doc) {
              final data = doc.data();
              data['id'] = doc.id; // Include document ID
              return data;
            }).toList());
  }
}

Trong một widget Flutter, stream này tích hợp trực tiếp với StreamBuilder để dựng lại UI trên mỗi thay đổi cơ sở dữ liệu. Firestore tự động xử lý quản lý kết nối, caching và lưu trữ ngoại tuyến.

Sẵn sàng chinh phục phỏng vấn Flutter?

Luyện tập với mô phỏng tương tác, flashcards và bài kiểm tra kỹ thuật.

Quy Tắc Bảo Mật Firestore Cho Ứng Dụng Flutter

Quy tắc bảo mật chạy trên máy chủ Firestore và kiểm soát quyền đọc/ghi ở cấp độ document. Nếu không có quy tắc phù hợp, bất kỳ người dùng nào đã xác thực đều có thể đọc hoặc sửa đổi bất kỳ document nào.

firestore.rulesjavascript
rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // Users can only access their own profile
    match /users/{userId} {
      allow read, update: if request.auth != null
                          && request.auth.uid == userId;
      allow create: if request.auth != null;
      allow delete: if false; // Prevent self-deletion
    }

    // Tasks belong to the user who created them
    match /tasks/{taskId} {
      allow read, write: if request.auth != null
                         && resource.data.userId == request.auth.uid;
      allow create: if request.auth != null
                    && request.resource.data.userId == request.auth.uid;
    }
  }
}

Biến request.auth.uid chứa ID của người dùng đã xác thực từ Firebase Auth. Các quy tắc tham chiếu resource.data kiểm tra các trường document hiện có, trong khi request.resource.data xác thực dữ liệu ghi đang đến.

Quy Tắc Bảo Mật Không Phải Tùy Chọn

Firestore mặc định từ chối mọi quyền truy cập ở chế độ production. Mỗi collection cần quy tắc rõ ràng. Một lỗi phổ biến trong các dự án Flutter: phát triển với quy tắc chế độ thử nghiệm (allow read, write: if true) và quên khóa lại trước khi triển khai production.

Lưu Trữ Ngoại Tuyến và Chiến Lược Caching

Firestore bật lưu trữ ngoại tuyến theo mặc định trên các nền tảng di động. Khi thiết bị mất kết nối, các thao tác đọc trả về dữ liệu đã được cache và các thao tác ghi xếp hàng cục bộ cho đến khi kết nối được khôi phục.

Hành vi này không đòi hỏi thêm mã Flutter nào: vẫn cùng các lệnh gọi get() và snapshots() hoạt động khi ngoại tuyến. Tuy nhiên, hai điểm cần lưu ý cho ứng dụng production:

  • Kích thước cache: Firestore cache tất cả document mà client đã đọc. Với các ứng dụng nhiều dữ liệu, hãy cấu hình Settings(cacheSizeBytes: Settings.CACHE_SIZE_UNLIMITED) hoặc đặt một giới hạn cụ thể.
  • Chỉ báo ghi đang chờ: Dùng SnapshotMetadata.hasPendingWrites để cho người dùng biết khi nào các thay đổi cục bộ chưa được đồng bộ lên máy chủ.
offline_aware_widget.dartdart
StreamBuilder<DocumentSnapshot>(
  stream: FirebaseFirestore.instance
      .collection('tasks')
      .doc(taskId)
      .snapshots(),
  builder: (context, snapshot) {
    if (!snapshot.hasData) return const CircularProgressIndicator();

    final data = snapshot.data!;
    final isPending = data.metadata.hasPendingWrites;

    return Row(
      children: [
        Text(data['title']),
        if (isPending) const Icon(Icons.cloud_upload, size: 16),
      ],
    );
  },
)

Cấu Trúc Một Ứng Dụng Flutter Firebase Cho Production

Một kiến trúc có khả năng mở rộng tách biệt logic Firebase khỏi mã UI. Mẫu repository cung cấp một lớp trừu tượng rõ ràng giúp đơn giản hóa việc kiểm thử và di chuyển backend trong tương lai.

task_repository.dartdart
abstract class TaskRepository {
  Future<String> create(String userId, String title);
  Stream<List<Task>> watchAll(String userId);
  Future<void> update(String id, Map<String, dynamic> fields);
  Future<void> delete(String id);
}

// firebase_task_repository.dart
class FirebaseTaskRepository implements TaskRepository {
  final _db = FirebaseFirestore.instance;

  
  Future<String> create(String userId, String title) async {
    final doc = await _db.collection('tasks').add({
      'userId': userId,
      'title': title,
      'completed': false,
      'createdAt': FieldValue.serverTimestamp(),
    });
    return doc.id;
  }

  
  Stream<List<Task>> watchAll(String userId) {
    return _db
        .collection('tasks')
        .where('userId', isEqualTo: userId)
        .orderBy('createdAt', descending: true)
        .snapshots()
        .map((s) => s.docs.map(Task.fromFirestore).toList());
  }

  // ... update and delete implementations
}

Với mẫu này, các giải pháp quản lý state như Riverpod hoặc BLoC sử dụng giao diện repository mà không cần biết về Firestore. Các bài kiểm thử đơn vị có thể thay thế bằng một mock repository trả về dữ liệu định trước.

Nâng Cấp Lên FlutterFire 5: Những Gì Bị Hỏng

Bản phát hành chính tháng 10/2026 (BoM 5.0.0, firebase_auth 7.0.0, cloud_firestore 7.0.0, firebase_core 5.0.0) thay đổi yêu cầu build nhiều hơn là API Dart. Những điểm làm hỏng build hoặc bị bắt lỗi khi review:

  • Android minSdk 24: các plugin dựa trên Firebase Android BoM 35. Dự án còn để minSdk 21 hoặc 23 sẽ không biên dịch được nữa.
  • Apple SDK 13: Firebase Apple SDK lên 13.0.0 với Swift Package Manager (12.19.0 với CocoaPods), và các gói Swift yêu cầu macOS 11.
  • App Check: các tham số của activate được đổi tên thành providerWeb, providerAndroid và providerApple.
  • Deprecated: setIndexConfigurationFromJSON bị đánh dấu deprecated trong cloud_firestore 7.0.0, và firebase_ml_model_downloader không còn được phát hành.
  • Đã bị xóa từ dòng 6.x: fetchSignInMethodsForEmail() và User.updateEmail(). Mã kiểm tra một email dùng nhà cung cấp nào trước khi đăng nhập phải được thiết kế lại, vì cơ chế bảo vệ chống liệt kê email (email enumeration protection) ẩn thông tin đó.

Danh sách đầy đủ theo từng gói nằm trong ghi chú phát hành FlutterFire và changelog của cloud_firestore.

Câu Hỏi Phỏng Vấn Firebase Cho Lập Trình Viên Flutter

Các buổi phỏng vấn kiểm tra cả hiểu biết khái niệm lẫn triển khai thực tế các dịch vụ Firebase. Những câu hỏi sau xuất hiện thường xuyên trong các buổi phỏng vấn lập trình viên Flutter năm 2026. Bộ câu hỏi phỏng vấn Flutter tổng quát hơn bao quát phần framework.

authStateChanges() khác với idTokenChanges() và userChanges() như thế nào?

authStateChanges() chỉ kích hoạt trên các sự kiện đăng nhập và đăng xuất. idTokenChanges() còn kích hoạt khi ID token được làm mới (khoảng mỗi giờ một lần). userChanges() ghi nhận tất cả những điều trên cộng với cập nhật hồ sơ như updateDisplayName(). Với hầu hết navigation guard, authStateChanges() là đủ.

Điều gì xảy ra khi một thao tác ghi Firestore diễn ra lúc thiết bị ngoại tuyến?

Thao tác ghi được lưu trong cache cục bộ và một hàng đợi ghi đang chờ. Các listener snapshots() ngay lập tức nhận dữ liệu cập nhật với metadata.hasPendingWrites == true. Khi kết nối được khôi phục, Firestore tự động đồng bộ các thao tác ghi đang chờ, và thao tác ghi đến máy chủ sau cùng sẽ thắng.

Nên mô hình hóa dữ liệu Firestore như thế nào cho một ứng dụng chat?

Một collection chats trong đó mỗi document chứa metadata (người tham gia, timestamp tin nhắn cuối), và một subcollection messages dưới mỗi document chat. Cấu trúc này cho phép truy vấn danh sách chat của người dùng một cách hiệu quả đồng thời phân trang tin nhắn trong từng cuộc trò chuyện. Hãy phi chuẩn hóa tin nhắn cuối vào document cha để tránh đọc subcollection cho khung nhìn danh sách.

Tại sao nên ưu tiên FieldValue.serverTimestamp() hơn DateTime.now()?

DateTime.now() dùng đồng hồ thiết bị, vốn có thể không chính xác hoặc bị thao túng. FieldValue.serverTimestamp() dùng đồng hồ máy chủ Firestore, đảm bảo thứ tự nhất quán trên mọi client. Điều này quan trọng với các tính năng như sắp xếp tin nhắn, bảng tin hoạt động và nhật ký kiểm toán.

Các truy vấn phức hợp được xử lý như thế nào trong Firestore, và yêu cầu về chỉ mục là gì?

Firestore yêu cầu một chỉ mục phức hợp cho các truy vấn kết hợp nhiều trường với mệnh đề where và orderBy. Chỉ mục một trường được tạo tự động, nhưng chỉ mục phức hợp phải được định nghĩa thủ công trong firestore.indexes.json hoặc qua Firebase console. Firestore ghi lại một liên kết trực tiếp để tạo chỉ mục còn thiếu khi một truy vấn thất bại.

Khi nào nên dùng transaction thay vì batched write?

Transaction cần thiết khi thao tác ghi phụ thuộc vào dữ liệu được đọc trong cùng thao tác, chẳng hạn chỉ giảm tồn kho khi còn lớn hơn 0. SDK chạy lại callback nếu một document đã đọc thay đổi trước khi commit, vì vậy callback không được có tác dụng phụ. Batched write thực hiện nhiều thao tác ghi một cách nguyên tử mà không đọc gì, ví dụ tạo một document và cập nhật một bộ đếm ở nơi khác. Hai cơ chế không hoạt động giống nhau khi ngoại tuyến: batch được xếp hàng, còn transaction thất bại khi không có kết nối.

dart
final db = FirebaseFirestore.instance;

// Transaction: read then write, retried on contention
await db.runTransaction((tx) async {
  final ref = db.collection('products').doc(id);
  final snap = await tx.get(ref);
  final stock = snap.get('stock') as int;
  if (stock <= 0) throw Exception('Out of stock');
  tx.update(ref, {'stock': stock - 1});
});

// Batched write: atomic writes, no reads
final batch = db.batch();
batch.set(db.collection('orders').doc(), {'productId': id});
batch.update(db.collection('stats').doc('orders'), {
  'count': FieldValue.increment(1),
});
await batch.commit();

Triển khai vai trò admin với Firebase như thế nào?

Bằng custom claims được thiết lập từ một môi trường tin cậy qua Admin SDK, không bao giờ từ client Flutter. Claim nằm bên trong ID token, nên quy tắc đọc nó dưới dạng request.auth.token.admin == true mà không cần tra cứu thêm document. Tài liệu custom claims giới hạn payload ở 1000 byte, và client chỉ thấy claim mới sau khi token được làm mới, điều mà currentUser.getIdToken(true) có thể ép buộc.

Quy tắc bảo mật và App Check khác nhau ở điểm nào?

Quy tắc bảo mật quyết định một người dùng cụ thể có được đọc hoặc ghi một document cụ thể hay không. App Check chứng thực rằng yêu cầu đến từ ứng dụng chính hãng trên một thiết bị thật, qua đó chặn các script dùng lại khóa API công khai. Chúng trả lời những câu hỏi khác nhau, nên ứng dụng production cần cả hai. Kể từ FlutterFire 5, App Check được kích hoạt với providerAndroid, providerApple và providerWeb.

Vì sao một màn hình Firestore có thể trở nên tốn kém, và phân trang được thực hiện ra sao?

Firestore tính phí theo mỗi lần đọc, ghi và xóa document. Một listener trên collection không giới hạn sẽ đọc mọi document khớp trong lần tải đầu tiên, sau đó một lần đọc cho mỗi document thay đổi. Phân trang dùng query cursor thay vì offset: limit(20) cho trang đầu, rồi startAfterDocument(lastDoc) cho trang tiếp theo, nhờ đó mỗi trang chỉ tốn chi phí cho số document nó trả về.

Firestore hay Realtime Database: chọn cái nào và vì sao?

Firestore lưu document trong các collection, hỗ trợ truy vấn kết hợp có chỉ mục và tính phí theo thao tác. Realtime Database lưu một cây JSON duy nhất, chỉ cung cấp truy vấn nông trên một khóa con và tính phí chủ yếu theo băng thông và dung lượng lưu trữ, phù hợp với các cập nhật nhỏ và rất thường xuyên như chỉ báo trạng thái trực tuyến. Phần lớn ứng dụng Flutter mới bắt đầu với Firestore và chỉ thêm Realtime Database cho tính năng presence.

Để chuẩn bị phỏng vấn Flutter sâu hơn, các module luyện tập chuyên biệt bao quát các chủ đề này với câu hỏi tương tác và thử thách tính giờ.

Bắt đầu luyện tập!

Kiểm tra kiến thức với mô phỏng phỏng vấn và bài kiểm tra kỹ thuật.

Nguồn Tham Khảo

Những Điểm Chính Về Flutter Firebase Cho Phỏng Vấn

  • FlutterFire BoM 5.1.0 đi kèm firebase_auth 7.0.1 và cloud_firestore 7.1.0, và yêu cầu minSdk Android 24
  • google_sign_in 7 thay GoogleSignIn().signIn() bằng GoogleSignIn.instance.initialize() rồi authenticate(), và Firebase chỉ cần idToken
  • authStateChanges() cung cấp một stream phản ứng để quản lý trạng thái đăng nhập trên toàn ứng dụng mà không cần kiểm tra thủ công
  • Đồng bộ hóa thời gian thực qua snapshots() loại bỏ polling và tích hợp trực tiếp với StreamBuilder để cập nhật UI tự động
  • Quy tắc bảo mật là bắt buộc cho production: luôn xác thực request.auth.uid đối chiếu với các trường quyền sở hữu document, và dùng custom claims cho vai trò
  • Transaction đọc rồi ghi kèm cơ chế thử lại, batched write chỉ ghi; phân trang dùng cursor vì mỗi lần đọc document đều bị tính phí
  • Lưu trữ ngoại tuyến hoạt động trên di động mà không cần thêm mã; dùng hasPendingWrites để truyền đạt trạng thái đồng bộ cho người dùng
  • Mẫu repository tách Firebase khỏi logic nghiệp vụ, giúp kiểm thử và di chuyển trong tương lai trở nên đơn giản
Thử thách hôm nay

Bạn có tìm ra lỗi trong Flutter không?

Một đoạn mã thật, một lỗi ẩn, mỗi ngày một lượt. Không cần tài khoản để thử.

Anthony Fillion-Maillet

Viết bởi

Anthony Fillion-Maillet

Người sáng lập SharpSkill

Lập trình viên fullstack hơn 10 năm. Anh điều hành SharpSkill và chịu trách nhiệm về mọi nội dung đăng tại đây.

Cập nhật ngày 9 tháng 11, 2026

Thẻ

#flutter
#firebase
#authentication
#firestore
#dart
#mobile development

Chia sẻ

Bài viết liên quan