# Flutter та Firebase у 2026: Автентифікація, Firestore та питання на співбесідах > Вичерпний посібник з інтеграції Flutter та Firebase у 2026 році — автентифікація, CRUD-операції у Firestore, синхронізація в реальному часі та найпоширеніші питання на технічних співбесідах. - Published: 2026-06-10 - Updated: 2026-06-10 - Author: SharpSkill - Tags: flutter, firebase, автентифікація, firestore, dart, мобільна розробка - Reading time: 12 min --- Інтеграція Flutter з Firebase залишається найпопулярнішим backend-рішенням для мобільних додатків у 2026 році, забезпечуючи автентифікацію, бази даних реального часу та хмарні функції в мільйонах застосунків. З виходом FlutterFire SDK v4.15 інструментарій суттєво дозрів — від спрощеного налаштування через `flutterfire configure` до нативної підтримки Firestore Pipelines та Firebase Admin Dart SDK. > **FlutterFire SDK v4.15 (2026)** > > Останній реліз FlutterFire містить firebase_auth v6.1.2 та cloud_firestore v6.4.1 з підтримкою Firestore Pipelines, TOTP-автентифікації на macOS та API validatePassword для застосування політик паролів. ## Налаштування Firebase в проекті Flutter Перед написанням будь-якого коду Firebase проект потребує коректної ініціалізації. FlutterFire CLI автоматизує реєстрацію платформи та генерує конфігураційні файли для Android, iOS, web та macOS. ```dart // main.dart 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()); } ``` Файл `firebase_options.dart` генерується автоматично після запуску `flutterfire configure`. Він містить API-ключі, ідентифікатори проекту та специфічні для платформи ідентифікатори — без необхідності ручного копіювання з консолі Firebase. ## Автентифікація Firebase: Email, Google та багатофакторна автентифікація Firebase Authentication керує ідентифікацією користувачів з мінімальним шаблонним кодом. Пакет `firebase_auth` підтримує email/пароль, провайдерів OAuth (Google, Apple, GitHub), телефонну верифікацію через SMS та багатофакторну автентифікацію (MFA). ### Реєстрація за допомогою email та пароля Найпоширеніший потік починається з email/пароль. Метод `createUserWithEmailAndPassword` повертає об'єкт `UserCredential`, що містить автентифікований об'єкт `User`. ```dart // auth_service.dart import 'package:firebase_auth/firebase_auth.dart'; class AuthService { final FirebaseAuth _auth = FirebaseAuth.instance; // Register with email and password Future 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 signIn(String email, String password) async { final credential = await _auth.signInWithEmailAndPassword( email: email, password: password, ); return credential.user; } // Reactive auth state stream Stream get authStateChanges => _auth.authStateChanges(); } ``` Потік `authStateChanges()` — це рекомендований спосіб відстежувати стан авторизації в усьому додатку. Він емітує поточного користувача `User` при підписці та спрацьовує знову при кожному вході або виході. ### Інтеграція входу через Google Провайдери OAuth потребують додаткового пакета. Вхід через Google запускає нативний вибирач облікових записів, а потім обмінює токен з Firebase. ```dart // google_auth.dart import 'package:firebase_auth/firebase_auth.dart'; import 'package:google_sign_in/google_sign_in.dart'; Future signInWithGoogle() async { // Trigger the native Google Sign-In flow final googleUser = await GoogleSignIn().signIn(); if (googleUser == null) throw Exception('Sign-in cancelled'); // Obtain auth details from the Google account final googleAuth = await googleUser.authentication; // Create a Firebase credential from the Google tokens final credential = GoogleAuthProvider.credential( accessToken: googleAuth.accessToken, idToken: googleAuth.idToken, ); // Sign in to Firebase with the Google credential return FirebaseAuth.instance.signInWithCredential(credential); } ``` Цей патерн застосовується до всіх провайдерів OAuth: отримати токен провайдера, загорнути його в credential Firebase, а потім викликати `signInWithCredential`. > **Валідація політики паролів** > > Firebase Auth v6.1+ містить API `validatePassword`, що дозволяє застосовувати політики паролів на стороні сервера. Політики можуть вимагати мінімальної довжини, великих та малих літер, цифр та спеціальних символів — усе налаштовується з консолі Firebase. ## CRUD-операції у Firestore та моделювання даних Cloud Firestore організовує дані в колекції та документи. На відміну від SQL-баз даних, Firestore не має схеми — кожен документ може містити різні поля. Ця гнучкість добре підходить для додатків Flutter, але вимагає дисциплінованого моделювання даних для уникнення проблем з продуктивністю. ### Запис та читання документів Операції Firestore є простими з пакетом `cloud_firestore`. Кожне читання та запис спрямоване на конкретний шлях документа. ```dart // firestore_service.dart 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 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?> 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 toggleComplete(String taskId, bool completed) async { await _db.collection(_collection).doc(taskId).update({ 'completed': completed, 'updatedAt': FieldValue.serverTimestamp(), }); } // Delete a document Future deleteTask(String taskId) async { await _db.collection(_collection).doc(taskId).delete(); } } ``` `FieldValue.serverTimestamp()` забезпечує послідовні мітки часу на всіх пристроях, використовуючи годинник сервера Firestore замість годинника клієнта. ### Потоки реального часу з snapshots() Firestore відзначається синхронізацією в реальному часі. Метод `snapshots()` повертає `Stream`, що емітує нові дані щоразу, коли базові документи змінюються — без необхідності опитування. ```dart // real_time_tasks.dart 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>> 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()); } } ``` У віджеті Flutter цей потік інтегрується безпосередньо зі `StreamBuilder` для перебудови інтерфейсу при кожній зміні в базі даних. Firestore автоматично керує з'єднаннями, кешуванням та офлайн-зберіганням. ## Правила безпеки Firestore для додатків Flutter Правила безпеки працюють на сервері Firestore та контролюють доступ до читання/запису на рівні документа. Без належних правил будь-який автентифікований користувач міг би прочитати або змінити будь-який документ. ```javascript // firestore.rules 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; } } } ``` Змінна `request.auth.uid` містить ідентифікатор автентифікованого користувача з Firebase Auth. Правила, що посилаються на `resource.data`, перевіряють існуючі поля документа, а `request.resource.data` валідує вхідні дані запису. > **Правила безпеки не є необов'язковими** > > Firestore за замовчуванням відхиляє весь доступ у виробничому режимі. Кожна колекція потребує явних правил. Поширена помилка в проектах Flutter: розробка з правилами тестового режиму (`allow read, write: if true`) та забуття про захист перед виробничим розгортанням. ## Офлайн-зберігання та стратегія кешування Firestore за замовчуванням вмикає офлайн-зберігання на мобільних платформах. Коли пристрій втрачає з'єднання, операції читання повертають дані з кешу, а операції запису ставляться в локальну чергу до відновлення з'єднання. Ця поведінка є прозорою для коду Flutter — ті самі виклики `get()` та `snapshots()` працюють офлайн. Проте для виробничих додатків важливі два аспекти: - **Розмір кешу**: Firestore кешує всі документи, які клієнт прочитав. Для додатків з великим обсягом даних варто налаштувати `Settings(cacheSizeBytes: Settings.CACHE_SIZE_UNLIMITED)` або встановити конкретний ліміт. Реліз v6.4.1 виправив баг, де необмежений кеш не застосовувався коректно на iOS. - **Індикатор очікуваних записів**: `SnapshotMetadata.hasPendingWrites` дозволяє показати користувачам, коли локальні зміни ще не синхронізовані з сервером. ```dart // offline_aware_widget.dart StreamBuilder( 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), ], ); }, ) ``` ## Архітектура виробничого додатку Flutter з Firebase Масштабована архітектура відокремлює логіку Firebase від коду інтерфейсу. Патерн репозиторію забезпечує чисту абстракційну верстку, що спрощує тестування та майбутні міграції бекенду. ```dart // task_repository.dart abstract class TaskRepository { Future create(String userId, String title); Stream> watchAll(String userId); Future update(String id, Map fields); Future delete(String id); } // firebase_task_repository.dart class FirebaseTaskRepository implements TaskRepository { final _db = FirebaseFirestore.instance; @override Future 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; } @override Stream> 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 } ``` З цим патерном рішення для керування станом, такі як Riverpod або BLoC, споживають інтерфейс репозиторію без відомості про Firestore. Модульні тести можуть підставити мок репозиторію, що повертає заздалегідь визначені дані. ## Поширені питання на співбесідах: Flutter та Firebase Співбесіди часто перевіряють як концептуальне розуміння, так і практичну реалізацію сервісів Firebase. Наступні питання регулярно з'являються на співбесідах з розробниками Flutter у 2026 році. **Чим `authStateChanges()` відрізняється від `idTokenChanges()` та `userChanges()`?** `authStateChanges()` спрацьовує лише при подіях входу та виходу. `idTokenChanges()` також спрацьовує при оновленні токена ідентифікації (приблизно кожних 60 хвилин). `userChanges()` охоплює все вищевказане плюс оновлення профілю, такі як `updateDisplayName()`. Для більшості навігаційних захистів достатньо `authStateChanges()`. **Що відбувається, коли запис у Firestore здійснюється, коли пристрій в офлайні?** Запис зберігається в локальному кеші та черзі очікуваних записів. Лістенери `snapshots()` негайно отримують оновлені дані з `metadata.hasPendingWrites == true`. Коли з'єднання відновлюється, Firestore автоматично синхронізує очікувані записи, використовуючи розв'язання конфліктів «останній запис перемагає» на рівні поля. **Як слід моделювати дані Firestore для додатку чату?** Поширений підхід: колекція `chats`, де кожен документ містить метадані (учасники, мітка часу останнього повідомлення), та підколекція `messages` під кожним документом чату. Ця структура дозволяє ефективно запитувати список чатів користувача, одночасно сторінкуючи повідомлення в кожній розмові. Денормалізація останнього повідомлення в батьківський документ дозволяє уникнути читання підколекції при відображенні списку. **Чому `FieldValue.serverTimestamp()` переважніший над `DateTime.now()`?** `DateTime.now()` використовує годинник пристрою, який може бути неточним або зманіпульованим. `FieldValue.serverTimestamp()` використовує годинник сервера Firestore, гарантуючи послідовне сортування на всіх клієнтах. Це важливо для таких функцій, як порядок повідомлень, стрічки активності та журнали аудиту. **Як обробляються складені запити у Firestore та які вимоги до індексів?** Firestore вимагає складного індексу для запитів, що поєднують кілька полів з клаузулами `where` та `orderBy`. Однопольні індекси створюються автоматично, але складені індекси треба визначити вручну у файлі `firestore.indexes.json` або через консоль Firebase. Коли запит завершується невдачею, Firestore логує пряме посилання для створення відсутнього індексу. Більше матеріалів для підготовки до співбесід з [Flutter та Firebase](/technologies/flutter/interview-questions/firebase-integration) доступно в інтерактивних модулях, які охоплюють ці теми з детальними поясненнями. --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/uk/blog/flutter/flutter-firebase-authentication-firestore-2026