Preguntas de entrevista sobre Firebase 2026: autenticación en Flutter, Firestore y reglas de seguridad
Preguntas de entrevista sobre Firebase para desarrolladores Flutter, con respuestas en Dart: streams de autenticación, Google Sign-In v7, CRUD y modelado en Firestore, reglas de seguridad, custom claims, transacciones y cambios de FlutterFire 5.

Las preguntas de entrevista sobre Firebase para puestos de Flutter giran en torno a cinco temas: los tres streams de estado de autenticación, el modelado de datos en Firestore, las reglas de seguridad, las escrituras offline y el modelo de costos detrás de cada lectura. Firebase sigue siendo el backend por defecto de las aplicaciones Flutter en 2026, y desde octubre de 2026 los plugins de FlutterFire se publican bajo el BoM 5.x (firebase_core 5.1.0, firebase_auth 7.0.1, cloud_firestore 7.1.0), con el minSdk de Android elevado a 24 y el SDK de Firebase para Apple 13 por debajo.
La versión actual de FlutterFire es el BoM 5.1.0: firebase_auth 7.0.1, cloud_firestore 7.1.0, firebase_core 5.1.0. La versión mayor 5.0.0 exige minSdk 24 en Android, se basa en el SDK de Firebase para Apple 13.0.0 y renombra los parámetros de activate en App Check. Firestore Pipelines, incorporado en cloud_firestore 6.3.0, suma nuevas expresiones en cada versión.
Preguntas de entrevista sobre Firebase: qué se pregunta en 2026
Los entrevistadores rara vez piden detalles memorizados de la API. Verifican si el candidato entiende dónde aplica Firebase las reglas, cuánto cuesta cada operación y qué ocurre cuando se cae la red. La siguiente tabla relaciona los temas recurrentes con lo que debe contener una buena respuesta. Cada uno se responde en detalle en la sección de preguntas de entrevista sobre Flutter y Firebase más abajo.
| Tema | Pregunta típica | Qué contiene una buena respuesta |
|---|---|---|
| Streams de autenticación | authStateChanges() vs idTokenChanges() vs userChanges() | Qué eventos emite cada uno y cuál protege la navegación |
| Seguridad | ¿Dónde se aplica el control de acceso? | Reglas de seguridad en el servidor, nunca validaciones en el cliente; App Check es otra capa |
| Roles | ¿Cómo implementar un rol de administrador? | Custom claims asignados con el Admin SDK y leídos mediante request.auth.token |
| Modelado de datos | Modelar una aplicación de chat | Subcolecciones, último mensaje desnormalizado, un documento por mensaje |
| Consistencia | ¿Transacción o escritura por lotes? | La transacción lee, luego escribe y se reintenta; el lote solo escribe, de forma atómica |
| Offline | ¿Qué pasa con una escritura sin conexión? | Caché local, hasPendingWrites, sincronización al reconectar |
| Costo | ¿Por qué esta pantalla sale cara? | Facturación por documento leído, listeners, paginación con cursores |
| Comparación | Firestore vs Realtime Database | Modelo de consultas, escalado, unidad de facturación |
Configuración de Firebase en un Proyecto Flutter
La inicialización de Firebase requiere configuración específica por plataforma que el FlutterFire CLI automatiza mediante el comando flutterfire configure. Este proceso genera el archivo firebase_options.dart con las credenciales de cada plataforma objetivo.
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());
}La llamada a ensureInitialized() garantiza que el binding de Flutter esté listo antes de inicializar servicios nativos. La inicialización asíncrona bloquea el arranque de la aplicación hasta que Firebase establece la conexión con los servicios configurados.
Autenticación Firebase: Email, Google y Multifactor
Firebase Authentication proporciona un sistema de identidad completo que gestiona el ciclo de vida de sesiones, tokens de actualización y verificación de credenciales. Admite email y contraseña, proveedores OAuth (Google, Apple, GitHub), verificación por SMS y autenticación multifactor, incluido TOTP en macOS desde firebase_auth 6.1.0. La implementación de autenticación por email constituye el punto de partida para la mayoría de aplicaciones.
Registro e Inicio de Sesión con Email y Contraseña
La clase FirebaseAuth expone métodos para crear cuentas y autenticar usuarios existentes. El manejo de excepciones específicas por código de error permite proporcionar retroalimentación contextual en la interfaz de usuario.
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();
}El stream authStateChanges() emite el User actual al suscribirse y vuelve a emitir en cada inicio o cierre de sesión, lo que permite que la interfaz reaccione automáticamente al estado de autenticación.
Las reglas de contraseña ya no tienen que vivir solo en el cliente: la API validatePassword (disponible desde firebase_auth 6.0.0) comprueba una contraseña contra la política configurada en la consola de Firebase, que puede exigir una longitud mínima, mayúsculas, minúsculas, números y caracteres especiales.
Integración de Google Sign-In
Los proveedores OAuth requieren un paquete adicional. Desde google_sign_in 7.0, el plugin es un singleton que se obtiene con GoogleSignIn.instance, debe inicializarse exactamente una vez y la autenticación está separada de la autorización. La llamada GoogleSignIn().signIn() que aparece en tutoriales antiguos ya no compila.
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;
}
}Este patrón aplica a todos los proveedores OAuth: obtener el token del proveedor, envolverlo en una credencial de Firebase y luego llamar a signInWithCredential. Cuando la aplicación también necesita llamar a una API de Google (Drive, Calendar), el token de acceso ahora se obtiene en un paso separado, authorizationClient.authorizeScopes, como describe la guía de migración de google_sign_in.
Un candidato que escribe GoogleSignIn().signIn() y lee accessToken desde authentication está citando la API anterior a la 7.0. En v7, authenticate() devuelve la cuenta, authentication solo contiene el idToken y los tokens de acceso para scopes adicionales requieren una llamada de autorización explícita.
Operaciones CRUD en Firestore y Modelado de Datos
Cloud Firestore organiza los datos en colecciones de documentos, donde cada documento contiene pares clave-valor. Las operaciones de escritura y lectura utilizan referencias a documentos o consultas sobre colecciones.
Escritura y Lectura de Documentos
Las operaciones básicas CRUD encapsulan la lógica de acceso a datos. El método add() genera IDs automáticamente, mientras que doc() permite especificar identificadores personalizados.
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();
}
}El uso de FieldValue.serverTimestamp() garantiza que las marcas de tiempo reflejen la hora del servidor, evitando inconsistencias causadas por relojes de dispositivos incorrectos.
Desde cloud_firestore 7.1.0, FieldValue.minimum y FieldValue.maximum se suman a FieldValue.serverTimestamp() entre las transformaciones del lado del servidor: conservan el menor o el mayor entre el valor almacenado y el entrante sin necesidad de una lectura previa, lo que sirve para contadores como un puntaje máximo.
Streams en Tiempo Real con snapshots()
Los streams de Firestore proporcionan actualizaciones en vivo cuando los datos subyacentes cambian. Las consultas compuestas con where() y orderBy() filtran y ordenan resultados antes de emitir eventos.
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());
}
}Las consultas que combinan where() y orderBy() requieren índices compuestos que Firestore sugiere crear automáticamente cuando se ejecuta la consulta por primera vez.
¿Listo para aprobar tus entrevistas de Flutter?
Practica con nuestros simuladores interactivos, flashcards y tests técnicos.
Reglas de Seguridad Firestore para Aplicaciones Flutter
Las reglas de seguridad de Firestore actúan como firewall en el servidor, validando cada operación de lectura y escritura antes de ejecutarla. La configuración predeterminada bloquea todo el acceso hasta que se definen reglas explícitas.
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;
}
}
}El contexto request.auth proporciona acceso al token JWT del usuario autenticado, mientras que resource.data contiene los datos actuales del documento y request.resource.data contiene los datos entrantes en operaciones de escritura.
Las reglas de seguridad de Firestore no son filtros de consulta. Una consulta que intenta leer documentos prohibidos por las reglas falla completamente en lugar de devolver un subconjunto filtrado. Las consultas deben estructurarse para solicitar únicamente datos que el usuario tiene permiso para leer.
Persistencia Offline y Estrategia de Caché
Firestore habilita la persistencia offline de forma predeterminada en aplicaciones Flutter. Los datos consultados se almacenan en caché local y las escrituras pendientes se sincronizan automáticamente cuando se restaura la conectividad.
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),
],
);
},
)La propiedad metadata.hasPendingWrites permite diferenciar entre datos confirmados en el servidor y mutaciones locales pendientes de sincronización. Esta distinción es crucial para interfaces que necesitan indicar el estado de sincronización.
Estructura de una Aplicación Flutter-Firebase en Producción
Las arquitecturas de producción separan la lógica de negocio de los detalles de implementación de Firebase mediante el patrón Repository. Esta abstracción facilita las pruebas unitarias y permite cambiar proveedores de backend sin modificar la capa de presentación.
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
}Con este patrón, soluciones de manejo de estado como Riverpod o BLoC consumen la interfaz del repositorio sin saber nada de Firestore. La inyección de dependencias mediante constructores permite proporcionar implementaciones mock durante las pruebas, mientras que la aplicación en producción utiliza la implementación real de Firebase.
Migrar a FlutterFire 5: qué se rompe
La versión mayor de octubre de 2026 (BoM 5.0.0, firebase_auth 7.0.0, cloud_firestore 7.0.0, firebase_core 5.0.0) cambia más los requisitos de compilación que las APIs de Dart. Los puntos que hacen fallar un build o una revisión de código:
minSdk24 en Android: los plugins se basan en el BoM de Firebase para Android 35. Un proyecto que sigue enminSdk21 o 23 deja de compilar.- SDK de Apple 13: el SDK de Firebase para Apple pasa a 13.0.0 con Swift Package Manager (12.19.0 con CocoaPods), y los paquetes Swift requieren macOS 11.
- App Check: los parámetros de
activatese renombran aproviderWeb,providerAndroidyproviderApple. - Deprecaciones:
setIndexConfigurationFromJSONqueda deprecado encloud_firestore7.0.0, yfirebase_ml_model_downloaderya no se publica. - Ya eliminados en la línea 6.x:
fetchSignInMethodsForEmail()yUser.updateEmail(). El código que verifica qué proveedor usa un email antes del inicio de sesión tiene que rediseñarse, porque la protección contra la enumeración de emails oculta esa información.
La lista completa por paquete está en las notas de versión de FlutterFire y en el changelog de cloud_firestore.
Preguntas de entrevista sobre Firebase para desarrolladores Flutter
Las entrevistas evalúan tanto la comprensión conceptual como la implementación práctica de los servicios de Firebase. Las siguientes preguntas aparecen con frecuencia en entrevistas para desarrolladores Flutter en 2026. La guía más amplia de preguntas de entrevista sobre Flutter cubre el lado del framework.
¿En qué se diferencia authStateChanges() de idTokenChanges() y userChanges()?
authStateChanges() solo emite en los eventos de inicio y cierre de sesión. idTokenChanges() también emite cuando se renueva el token ID (aproximadamente cada hora). userChanges() captura todo lo anterior más las actualizaciones de perfil como updateDisplayName(). Para la mayoría de los guards de navegación, authStateChanges() es suficiente.
¿Qué ocurre cuando se realiza una escritura en Firestore con el dispositivo sin conexión?
La escritura se guarda en la caché local y en una cola de escrituras pendientes. Los listeners de snapshots() reciben de inmediato los datos actualizados con metadata.hasPendingWrites == true. Cuando vuelve la conectividad, Firestore sincroniza automáticamente las escrituras pendientes, y gana la última escritura que llega al servidor.
¿Cómo se modelan los datos de Firestore para una aplicación de chat?
Una colección chats donde cada documento contiene metadatos (participantes, marca de tiempo del último mensaje), y una subcolección messages bajo cada documento de chat. Esta estructura permite consultar de forma eficiente la lista de chats de un usuario mientras se paginan los mensajes de cada conversación. El último mensaje se desnormaliza en el documento padre para no leer la subcolección en la vista de lista.
¿Por qué conviene FieldValue.serverTimestamp() en lugar de DateTime.now()?
DateTime.now() usa el reloj del dispositivo, que puede ser impreciso o estar manipulado. FieldValue.serverTimestamp() usa el reloj del servidor de Firestore y garantiza un orden consistente entre todos los clientes. Esto importa en funciones como el orden de los mensajes, los feeds de actividad y los registros de auditoría.
¿Cómo maneja Firestore las consultas compuestas y qué índices requieren?
Firestore exige un índice compuesto para las consultas que combinan varios campos con cláusulas where y orderBy. Los índices de un solo campo se crean automáticamente, pero los compuestos deben definirse a mano en firestore.indexes.json o desde la consola de Firebase. Cuando una consulta falla, Firestore registra un enlace directo para crear el índice faltante.
¿Cuándo usar una transacción en lugar de una escritura por lotes?
Una transacción es necesaria cuando la escritura depende de datos leídos en la misma operación, por ejemplo descontar stock solo si es mayor que cero. El SDK reintenta el callback si un documento leído cambia antes del commit, así que el callback no debe tener efectos secundarios. Una escritura por lotes realiza varias escrituras de forma atómica sin ninguna lectura, por ejemplo crear un documento y actualizar un contador en otro lugar. Sin conexión no se comportan igual: el lote queda en cola, la transacción falla.
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();¿Cómo se implementa un rol de administrador con Firebase?
Con custom claims asignados desde un entorno de confianza mediante el Admin SDK, nunca desde el cliente Flutter. El claim viaja dentro del token ID, así que las reglas lo leen como request.auth.token.admin == true sin consultar otro documento. La documentación de custom claims limita el payload a 1000 bytes, y el cliente solo ve un claim nuevo después de renovar el token, algo que currentUser.getIdToken(true) fuerza.
¿Cuál es la diferencia entre las reglas de seguridad y App Check?
Las reglas de seguridad deciden si un usuario determinado puede leer o escribir un documento determinado. App Check certifica que la solicitud proviene de la aplicación legítima en un dispositivo legítimo, lo que bloquea scripts que reutilizan la API key pública. Responden preguntas distintas, por lo que una aplicación en producción necesita ambas. Desde FlutterFire 5, App Check se activa con providerAndroid, providerApple y providerWeb.
¿Por qué una pantalla de Firestore puede salir cara y cómo se pagina?
Firestore factura cada lectura, escritura y eliminación de documento. Un listener sobre una colección sin límite lee todos los documentos que coinciden en la primera carga y luego una lectura por cada documento modificado. La paginación usa cursores de consulta en lugar de offsets: limit(20) para la primera página y luego startAfterDocument(lastDoc) para la siguiente, de modo que cada página solo cuesta los documentos que devuelve.
¿Firestore o Realtime Database: cuál y por qué?
Firestore almacena documentos en colecciones, admite consultas compuestas con índices y factura por operación. Realtime Database almacena un único árbol JSON, ofrece consultas superficiales sobre una sola clave hija y factura principalmente por ancho de banda y almacenamiento, lo que encaja con actualizaciones pequeñas y muy frecuentes como los indicadores de presencia. La mayoría de las aplicaciones Flutter nuevas arrancan con Firestore y suman Realtime Database solo para la presencia.
Para profundizar en la preparación de entrevistas de Flutter, los módulos de práctica dedicados cubren estos temas con cuestionarios interactivos y desafíos cronometrados.
¡Empieza a practicar!
Pon a prueba tu conocimiento con nuestros simuladores de entrevista y tests técnicos.
Fuentes
- Notas de versión de Firebase para Flutter: contenido de los BoM 5.0.0 y 5.1.0, minSdk 24, cambio de nombre de los parámetros de App Check
- Changelog de cloud_firestore: Pipelines en 6.3.0,
FieldValue.minimum/maximumy distancia defindNearesten 7.1.0 - Changelog de firebase_auth:
validatePassworden 6.0.0, TOTP en macOS en 6.1.0, eliminación defetchSignInMethodsForEmail - Guía de migración de google_sign_in: singleton,
initialize,authenticate, autorización separada en 7.0 - Custom claims de Firebase: límite de 1000 bytes y renovación del token
Claves de Flutter y Firebase para entrevistas
- FlutterFire BoM 5.1.0 incluye
firebase_auth7.0.1 ycloud_firestore7.1.0, y exigeminSdk24 en Android google_sign_in7 reemplazaGoogleSignIn().signIn()porGoogleSignIn.instance.initialize()y luegoauthenticate(), y Firebase solo necesita elidTokenauthStateChanges()ofrece un stream reactivo para manejar el estado de sesión en toda la aplicación sin comprobaciones manuales- La sincronización en tiempo real con
snapshots()elimina el polling y se integra directamente conStreamBuilderpara actualizar la interfaz automáticamente - Las reglas de seguridad son obligatorias en producción: siempre validar
request.auth.uidcontra los campos de propiedad del documento y usar custom claims para los roles - Las transacciones leen y luego escriben con reintentos, las escrituras por lotes solo escriben; la paginación usa cursores porque se factura cada documento leído
- La persistencia offline funciona sin código adicional en móviles;
hasPendingWritespermite mostrar al usuario el estado de sincronización - El patrón Repository desacopla Firebase de la lógica de negocio, lo que simplifica las pruebas y las migraciones futuras
¿Sabrías detectar el bug en Flutter?
Un fragmento real, un bug oculto, un intento al día. Sin cuenta para probar.

Escrito por
Anthony Fillion-MailletFundador de SharpSkill
Desarrollador fullstack desde hace más de 10 años. Dirige SharpSkill y responde por todo lo que se publica aquí.
Actualizado el 9 de noviembre de 2026
Compartir
Artículos relacionados

Trabajos freelance para desarrolladores Flutter en 2026: dónde encontrar contratos, tarifas diarias, cómo prepararse
Guía práctica para encontrar trabajos freelance Flutter en 2026: dónde se publican los contratos, tarifas diarias por país, qué esperan los clientes y cómo prepararse para entrevistas técnicas.

Empleos para desarrolladores Flutter en 2026: dónde buscar, rangos salariales y preparación para entrevistas
Guía completa del mercado laboral Flutter en 2026: plataformas de reclutamiento, rangos salariales por región, habilidades demandadas y consejos para superar entrevistas técnicas.

Flutter Impeller en 2026: Arquitectura del motor de renderizado, mejoras de rendimiento y preguntas de entrevista
Guía completa sobre Flutter Impeller en 2026: arquitectura del motor de renderizado, eliminación del shader jank, benchmarks de rendimiento y preguntas técnicas para entrevistas de trabajo.