Pytania rekrutacyjne z Firebase 2026: Flutter Auth, Firestore i reguły bezpieczeństwa

Pytania rekrutacyjne z Firebase dla programistów Flutter z odpowiedziami w Darcie: strumienie stanu auth, Google Sign-In v7, CRUD i modelowanie w Firestore, reguły bezpieczeństwa, custom claims, transakcje i zmiany w FlutterFire 5.

Flutter i Firebase w 2026: Uwierzytelnianie, Firestore i pytania rekrutacyjne

Pytania rekrutacyjne z Firebase na stanowiska Flutter krążą wokół pięciu tematów: trzech strumieni stanu uwierzytelniania, modelowania danych w Firestore, reguł bezpieczeństwa, zapisów offline i modelu kosztów stojącego za każdym odczytem. Firebase pozostaje w 2026 roku domyślnym backendem aplikacji Flutter, a od października 2026 wtyczki FlutterFire są wydawane jako BoM 5.x (firebase_core 5.1.0, firebase_auth 7.0.1, cloud_firestore 7.1.0), z podniesionym na Androidzie minSdk do 24 i Firebase Apple SDK 13 pod spodem.

FlutterFire BoM 5.1.0 (październik 2026)

Aktualne wydanie FlutterFire to BoM 5.1.0: firebase_auth 7.0.1, cloud_firestore 7.1.0, firebase_core 5.1.0. Wersja główna 5.0.0 wymaga na Androidzie minSdk 24, opiera się na Firebase Apple SDK 13.0.0 i zmienia nazwy parametrów activate w App Check. Firestore Pipelines, dodane w cloud_firestore 6.3.0, zyskują nowe wyrażenia w każdym wydaniu.

Pytania rekrutacyjne z Firebase: o co pytają w 2026

Rekruterzy rzadko pytają o szczegóły API. Sprawdzają, czy kandydat rozumie, gdzie Firebase egzekwuje reguły, ile kosztuje każda operacja i co się dzieje po utracie sieci. Poniższa tabela zestawia powracające tematy z tym, co musi zawierać mocna odpowiedź. Każdy z nich jest omówiony szczegółowo niżej, w sekcji pytań rekrutacyjnych z Firebase dla programistów Flutter.

TematTypowe pytanieCo zawiera mocna odpowiedź
Strumienie authauthStateChanges() vs idTokenChanges() vs userChanges()Jakie zdarzenia emituje każdy z nich i który chroni nawigację
BezpieczeństwoGdzie egzekwowana jest kontrola dostępu?W regułach bezpieczeństwa na serwerze, nigdy w sprawdzeniach po stronie klienta; App Check to osobna warstwa
RoleJak zaimplementować rolę administratora?Custom claims ustawiane przez Admin SDK, odczytywane przez request.auth.token
Modelowanie danychZamodeluj aplikację czatuPodkolekcje, zdenormalizowana ostatnia wiadomość, jeden dokument na wiadomość
SpójnośćTransakcja czy zapis wsadowy?Transakcja czyta, potem zapisuje i ponawia próbę; batch tylko zapisuje, atomowo
OfflineCo dzieje się z zapisem offline?Lokalna pamięć podręczna, hasPendingWrites, synchronizacja po odzyskaniu połączenia
KosztyDlaczego ten ekran jest drogi?Opłata za każdy odczytany dokument, listenery, paginacja kursorami
PorównanieFirestore vs Realtime DatabaseModel zapytań, skalowanie, jednostka rozliczeniowa

Konfiguracja Firebase w projekcie Flutter

Przed napisaniem jakiegokolwiek kodu Firebase projekt wymaga prawidłowej inicjalizacji. FlutterFire CLI automatyzuje rejestrację platformy i generuje pliki konfiguracyjne dla Android, iOS, web oraz 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());
}

Plik firebase_options.dart jest generowany automatycznie po uruchomieniu flutterfire configure. Zawiera klucze API, identyfikatory projektu i identyfikatory specyficzne dla platformy, więc nic nie trzeba ręcznie kopiować z konsoli Firebase.

Uwierzytelnianie Firebase: Email, Google i uwierzytelnianie wielopoziomowe

Firebase Authentication obsługuje tożsamość użytkowników przy minimalnej ilości kodu szablonowego. Pakiet firebase_auth wspiera email/hasło, dostawców OAuth (Google, Apple, GitHub), weryfikację telefoniczną przez SMS oraz uwierzytelnianie wielopoziomowe (MFA), w tym TOTP na macOS od firebase_auth 6.1.0.

Rejestracja za pomocą adresu email i hasła

Najczęstszy przepływ rozpoczyna się od email/hasło. Metoda createUserWithEmailAndPassword zwraca obiekt UserCredential zawierający uwierzytelniony obiekt User.

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();
}

Strumień authStateChanges() to rekomendowany sposób śledzenia stanu logowania w całej aplikacji. Emituje bieżącego użytkownika User przy subskrypcji i reaguje ponownie przy każdym zdarzeniu logowania lub wylogowania.

Reguły haseł nie muszą już żyć wyłącznie w kliencie: API validatePassword (dostępne od firebase_auth 6.0.0) sprawdza hasło względem polityki skonfigurowanej w konsoli Firebase, która może wymagać minimalnej długości, wielkich i małych liter, cyfr oraz znaków specjalnych.

Integracja logowania przez Google

Dostawcy OAuth wymagają dodatkowego pakietu. Od google_sign_in 7.0 wtyczka jest singletonem dostępnym przez GoogleSignIn.instance, musi zostać zainicjalizowana dokładnie raz, a uwierzytelnianie jest oddzielone od autoryzacji. Wywołanie GoogleSignIn().signIn() ze starszych tutoriali już się nie kompiluje.

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;
  }
}

Ten wzorzec stosuje się do wszystkich dostawców OAuth: uzyskanie tokenu dostawcy, opakowanie go w credential Firebase, a następnie wywołanie signInWithCredential. Gdy aplikacja musi też wywoływać API Google (Drive, Calendar), token dostępu pochodzi teraz z osobnego kroku, authorizationClient.authorizeScopes, opisanego w przewodniku migracji google_sign_in.

Pułapka rekrutacyjna: Google Sign-In v7

Kandydat, który pisze GoogleSignIn().signIn() i odczytuje accessToken z authentication, cytuje API sprzed wersji 7.0. W v7 authenticate() zwraca konto, authentication zawiera tylko idToken, a tokeny dostępu do dodatkowych zakresów wymagają jawnego wywołania autoryzacji.

Operacje CRUD w Firestore i modelowanie danych

Cloud Firestore organizuje dane w kolekcje i dokumenty. W przeciwieństwie do baz SQL, Firestore nie wymaga schematu: każdy dokument może zawierać inne pola. Ta elastyczność dobrze pasuje do aplikacji Flutter, ale wymaga zdyscyplinowanego modelowania danych, aby uniknąć problemów z wydajnością.

Zapis i odczyt dokumentów

Operacje Firestore są proste dzięki pakietowi cloud_firestore. Każdy odczyt i zapis dotyczy konkretnej ścieżki dokumentu.

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() zapewnia spójne znaczniki czasu na wszystkich urządzeniach, wykorzystując zegar serwera Firestore zamiast zegara klienta. Od cloud_firestore 7.1.0 do transformacji po stronie serwera dołączają FieldValue.minimum i FieldValue.maximum: zachowują mniejszą lub większą z wartości zapisanej i przychodzącej bez odczytu, co pasuje do liczników takich jak najlepszy wynik.

Strumienie czasu rzeczywistego z snapshots()

Firestore wyróżnia się synchronizacją w czasie rzeczywistym. Metoda snapshots() zwraca Stream, który emituje nowe dane za każdym razem, gdy bazowe dokumenty ulegną zmianie, bez konieczności odpytywania.

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());
  }
}

W widgecie Flutter ten strumień integruje się bezpośrednio z StreamBuilder, aby przebudowywać interfejs przy każdej zmianie w bazie danych. Firestore automatycznie zarządza połączeniami, buforowaniem i trwałością offline.

Gotowy na rozmowy o Flutter?

Ćwicz z naszymi interaktywnymi symulatorami, flashcards i testami technicznymi.

Reguły bezpieczeństwa Firestore dla aplikacji Flutter

Reguły bezpieczeństwa działają na serwerze Firestore i kontrolują dostęp do odczytu/zapisu na poziomie dokumentu. Bez odpowiednich reguł każdy uwierzytelniony użytkownik mógłby odczytać lub zmodyfikować dowolny dokument.

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;
    }
  }
}

Zmienna request.auth.uid zawiera identyfikator uwierzytelnionego użytkownika z Firebase Auth. Reguły odwołujące się do resource.data sprawdzają istniejące pola dokumentu, natomiast request.resource.data waliduje przychodzące dane zapisu.

Reguły bezpieczeństwa nie są opcjonalne

Firestore domyślnie odmawia wszelkiego dostępu w trybie produkcyjnym. Każda kolekcja wymaga jawnych reguł. Częsty błąd w projektach Flutter: rozwijanie aplikacji z regułami trybu testowego (allow read, write: if true) i zapominanie o zabezpieczeniu przed wdrożeniem produkcyjnym.

Trwałość offline i strategia buforowania

Firestore domyślnie włącza trwałość offline na platformach mobilnych. Gdy urządzenie traci łączność, operacje odczytu zwracają dane z pamięci podręcznej, a operacje zapisu kolejkują się lokalnie do momentu wznowienia połączenia.

To zachowanie nie wymaga dodatkowego kodu we Flutterze: te same wywołania get() i snapshots() działają offline. Jednak w aplikacjach produkcyjnych istotne są dwie kwestie:

  • Rozmiar pamięci podręcznej: Firestore buforuje wszystkie dokumenty, które klient odczytał. Dla aplikacji z dużą ilością danych warto skonfigurować Settings(cacheSizeBytes: Settings.CACHE_SIZE_UNLIMITED) lub ustawić konkretny limit.
  • Wskaźnik oczekujących zapisów: Właściwość SnapshotMetadata.hasPendingWrites pozwala pokazać użytkownikom, kiedy lokalne zmiany nie zostały jeszcze zsynchronizowane z serwerem.
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),
      ],
    );
  },
)

Architektura produkcyjnej aplikacji Flutter z Firebase

Skalowalna architektura oddziela logikę Firebase od kodu UI. Wzorzec repozytorium zapewnia czystą warstwę abstrakcji, która upraszcza testowanie i przyszłe migracje backendu.

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
}

Dzięki temu wzorcowi rozwiązania zarządzania stanem, takie jak Riverpod czy BLoC, konsumują interfejs repozytorium bez wiedzy o Firestore. Testy jednostkowe mogą podstawić mocka repozytorium zwracającego predefiniowane dane.

Migracja do FlutterFire 5: co przestaje działać

Październikowe wydanie główne z 2026 roku (BoM 5.0.0, firebase_auth 7.0.0, cloud_firestore 7.0.0, firebase_core 5.0.0) zmienia bardziej wymagania budowania niż API Darta. Punkty, na których pada build lub code review:

  • Android minSdk 24: wtyczki opierają się na Firebase Android BoM 35. Projekt nadal ustawiony na minSdk 21 lub 23 przestaje się kompilować.
  • Apple SDK 13: Firebase Apple SDK przechodzi na 13.0.0 ze Swift Package Manager (12.19.0 z CocoaPods), a pakiety Swift wymagają macOS 11.
  • App Check: parametry activate zmieniają nazwy na providerWeb, providerAndroid i providerApple.
  • Wycofania: setIndexConfigurationFromJSON jest oznaczone jako deprecated w cloud_firestore 7.0.0, a firebase_ml_model_downloader nie jest już publikowany.
  • Usunięte już w linii 6.x: fetchSignInMethodsForEmail() i User.updateEmail(). Kod, który przed logowaniem sprawdza, jakiego dostawcy używa dany adres email, trzeba przeprojektować, ponieważ ochrona przed enumeracją adresów email ukrywa tę informację.

Pełna lista zmian dla każdego pakietu znajduje się w informacjach o wydaniach FlutterFire i w changelogu cloud_firestore.

Pytania rekrutacyjne z Firebase dla programistów Flutter

Rozmowy kwalifikacyjne często sprawdzają zarówno zrozumienie koncepcyjne, jak i praktyczną implementację usług Firebase. Poniższe pytania regularnie pojawiają się na rozmowach z programistami Flutter w 2026 roku. Stronę samego frameworka obejmuje szerszy przewodnik po pytaniach rekrutacyjnych z Fluttera.

Czym różni się authStateChanges() od idTokenChanges() i userChanges()?

authStateChanges() reaguje wyłącznie na zdarzenia logowania i wylogowania. idTokenChanges() reaguje dodatkowo na odświeżenie tokenu ID (mniej więcej co 60 minut). userChanges() obejmuje wszystkie powyższe zdarzenia plus aktualizacje profilu, takie jak updateDisplayName(). Do większości zabezpieczeń nawigacyjnych wystarczający jest authStateChanges().

Co dzieje się, gdy zapis do Firestore następuje, gdy urządzenie jest offline?

Zapis jest przechowywany w lokalnej pamięci podręcznej i kolejce oczekujących zapisów. Listenery snapshots() natychmiast otrzymują zaktualizowane dane z metadata.hasPendingWrites == true. Po wznowieniu łączności Firestore automatycznie synchronizuje oczekujące zapisy, a wygrywa ostatni zapis, który dotrze do serwera.

Jak powinno wyglądać modelowanie danych Firestore dla aplikacji czatu?

Popularne podejście: kolekcja chats, gdzie każdy dokument zawiera metadane (uczestnicy, znacznik czasu ostatniej wiadomości) oraz podkolekcja messages pod każdym dokumentem czatu. Ta struktura umożliwia efektywne zapytania o listę czatów użytkownika przy jednoczesnym stronicowaniu wiadomości w każdej konwersacji. Denormalizacja ostatniej wiadomości do dokumentu nadrzędnego pozwala uniknąć odczytywania podkolekcji przy wyświetlaniu listy.

Dlaczego FieldValue.serverTimestamp() jest preferowane nad DateTime.now()?

DateTime.now() korzysta z zegara urządzenia, który może być niedokładny lub zmanipulowany. FieldValue.serverTimestamp() wykorzystuje zegar serwera Firestore, gwarantując spójne sortowanie na wszystkich klientach. Ma to znaczenie dla funkcji takich jak kolejność wiadomości, kanały aktywności i logi audytu.

Jak obsługiwane są zapytania złożone w Firestore i jakie są wymagania dotyczące indeksów?

Firestore wymaga indeksu złożonego dla zapytań łączących wiele pól z klauzulami where i orderBy. Indeksy jednopolowe są tworzone automatycznie, ale indeksy złożone muszą być zdefiniowane ręcznie w pliku firestore.indexes.json lub przez konsolę Firebase. Gdy zapytanie kończy się niepowodzeniem, Firestore loguje bezpośredni link do utworzenia brakującego indeksu.

Kiedy użyć transakcji zamiast zapisu wsadowego?

Transakcja jest potrzebna, gdy zapis zależy od danych odczytanych w tej samej operacji, na przykład zmniejszenie stanu magazynowego tylko wtedy, gdy jest większy od zera. SDK ponawia callback, jeśli odczytany dokument zmieni się przed zatwierdzeniem, więc callback nie może mieć efektów ubocznych. Zapis wsadowy (batch) wykonuje kilka zapisów atomowo bez żadnego odczytu, na przykład utworzenie dokumentu i aktualizację licznika w innym miejscu. Offline zachowują się inaczej: batch trafia do kolejki, transakcja bez połączenia kończy się błędem.

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();

Jak zaimplementować rolę administratora w Firebase?

Za pomocą custom claims ustawianych z zaufanego środowiska przez Admin SDK, nigdy z klienta Flutter. Claim jest przenoszony w tokenie ID, więc reguły odczytują go jako request.auth.token.admin == true bez dodatkowego odczytu dokumentu. Dokumentacja custom claims ogranicza ładunek do 1000 bajtów, a klient widzi nowy claim dopiero po odświeżeniu tokenu, które wymusza currentUser.getIdToken(true).

Czym różnią się reguły bezpieczeństwa od App Check?

Reguły bezpieczeństwa decydują, czy dany użytkownik może odczytać lub zapisać dany dokument. App Check poświadcza, że żądanie pochodzi z oryginalnej aplikacji na prawdziwym urządzeniu, co blokuje skrypty wykorzystujące publiczny klucz API. Odpowiadają na różne pytania, dlatego aplikacja produkcyjna potrzebuje obu. Od FlutterFire 5 App Check aktywuje się parametrami providerAndroid, providerApple i providerWeb.

Dlaczego ekran oparty na Firestore może być drogi i jak działa paginacja?

Firestore nalicza opłaty za każdy odczyt, zapis i usunięcie dokumentu. Listener na nieograniczonej kolekcji przy pierwszym załadowaniu odczytuje każdy pasujący dokument, a potem wykonuje jeden odczyt na każdy zmieniony dokument. Paginacja używa kursorów zapytań zamiast offsetów: limit(20) dla pierwszej strony, potem startAfterDocument(lastDoc) dla kolejnej, więc każda strona kosztuje tylko tyle dokumentów, ile zwraca.

Firestore czy Realtime Database: co wybrać i dlaczego?

Firestore przechowuje dokumenty w kolekcjach, obsługuje zapytania złożone z indeksami i nalicza opłaty za operacje. Realtime Database przechowuje jedno drzewo JSON, oferuje płytkie zapytania po jednym kluczu potomnym i nalicza opłaty głównie za transfer i przechowywanie, co pasuje do małych, bardzo częstych aktualizacji, takich jak wskaźniki obecności. Większość nowych aplikacji Flutter zaczyna od Firestore i dodaje Realtime Database tylko do obsługi obecności.

Więcej materiałów do przygotowania do rozmów kwalifikacyjnych z Flutter i Firebase dostępnych jest w interaktywnych modułach ćwiczeniowych, które obejmują te zagadnienia w formie interaktywnych quizów i zadań na czas.

Zacznij ćwiczyć!

Sprawdź swoją wiedzę z naszymi symulatorami rozmów i testami technicznymi.

Źródła

Najważniejsze wnioski o Flutter i Firebase przed rozmową rekrutacyjną

  • FlutterFire BoM 5.1.0 zawiera firebase_auth 7.0.1 i cloud_firestore 7.1.0 oraz wymaga na Androidzie minSdk 24
  • google_sign_in 7 zastępuje GoogleSignIn().signIn() wywołaniem GoogleSignIn.instance.initialize(), a potem authenticate(), a Firebase potrzebuje tylko idToken
  • authStateChanges() dostarcza reaktywny strumień do zarządzania stanem logowania w całej aplikacji bez ręcznych sprawdzeń
  • Synchronizacja w czasie rzeczywistym przez snapshots() eliminuje odpytywanie i współpracuje bezpośrednio ze StreamBuilder, automatycznie aktualizując interfejs
  • Reguły bezpieczeństwa są obowiązkowe na produkcji: request.auth.uid należy zawsze porównywać z polami własności dokumentu, a role realizować przez custom claims
  • Transakcja czyta, potem zapisuje i ponawia próbę, zapis wsadowy tylko zapisuje; paginacja używa kursorów, bo każdy odczytany dokument jest płatny
  • Trwałość offline działa na urządzeniach mobilnych bez dodatkowego kodu; hasPendingWrites pozwala informować użytkowników o stanie synchronizacji
  • Wzorzec repozytorium oddziela Firebase od logiki biznesowej, co ułatwia testowanie i przyszłe migracje
Wyzwanie dnia

Znajdziesz błąd w Flutter?

Prawdziwy fragment kodu, ukryty błąd, jedna próba dziennie. Bez konta, żeby spróbować.

Anthony Fillion-Maillet

Autor:

Anthony Fillion-Maillet

Założyciel SharpSkill

Programista fullstack od ponad 10 lat. Prowadzi SharpSkill i odpowiada za wszystko, co się tu ukazuje.

Zaktualizowano 9 listopada 2026

Tagi

#flutter
#firebase
#uwierzytelnianie
#firestore
#dart
#programowanie mobilne

Udostępnij

Powiązane artykuły