Como Usar a API Firebase: Guia Completo de Integração (2026)

Ashley Innocent

Ashley Innocent

23 março 2026

Como Usar a API Firebase: Guia Completo de Integração (2026)

Você está construindo um aplicativo. Usuários precisam fazer login. Dados precisam sincronizar em tempo real. Arquivos precisam de armazenamento. Você poderia provisionar servidores, configurar bancos de dados e gerenciar infraestrutura por semanas. Ou você poderia usar o Firebase.

O Firebase impulsiona mais de 1,5 milhão de aplicativos, incluindo The New York Times, Duolingo e Alibaba. Desenvolvedores o escolhem porque ele remove a complexidade do backend. Você se concentra nos recursos, não na manutenção do servidor. Mas a API do Firebase tem suas particularidades. Fluxos de autenticação confundem iniciantes. Regras de banco de dados atrapalham desenvolvedores experientes. Cloud Functions parecem mágicas até que você entenda os gatilhos.

Eu integrei o Firebase em aplicativos de produção que atendem milhões de usuários. Cometi todos os erros possíveis: chaves de conta de serviço expostas, consultas ineficientes, funções quebradas implantadas. Este guia destila essas lições.

Você aprenderá autenticação, operações de banco de dados, Cloud Functions e armazenamento. Você verá código funcionando, não apenas teoria. Você evitará as armadilhas que causam problemas em produção.

💡
Testar APIs Firebase se torna mais fácil com ferramentas de cliente API adequadas. O Apidog permite organizar endpoints, testar fluxos de autenticação e compartilhar coleções com sua equipe. Mostraremos onde ele se encaixa naturalmente no fluxo de trabalho.
button

O Que É a API do Firebase e Por Que Ela Importa?

Firebase não é uma única API. É um conjunto de serviços de backend acessados por meio de SDKs unificados e endpoints REST.

Principais Serviços do Firebase

Serviço Propósito Tipo de API
Authentication Login e identidade do usuário SDK + REST
Firestore Database Banco de dados de documentos NoSQL SDK + REST
Realtime Database Sincronização JSON em tempo real SDK + REST
Cloud Storage Armazenamento de arquivos e CDN SDK + REST
Cloud Functions Computação sem servidor CLI de Implantação
Hosting Hospedagem web estática CLI de Implantação
Cloud Messaging Notificações push API HTTP v1

Quando o Firebase Faz Sentido

O Firebase resolve problemas específicos muito bem:

Use o Firebase quando:

Pule o Firebase quando:

A Arquitetura da API do Firebase

O Firebase usa uma abordagem híbrida:

┌─────────────────────────────────────────────────────────┐
│                    Sua Aplicação                         │
├─────────────────────────────────────────────────────────┤
│  Firebase SDK (Cliente)                                  │
│  - Gerencia tokens de autenticação automaticamente      │
│  - Gerencia cache offline                                │
│  - Listeners em tempo real                               │
└─────────────────────────────────────────────────────────┘
                          │
                          │ HTTPS + WebSocket
                          ▼
┌─────────────────────────────────────────────────────────┐
│                   Backend do Firebase                    │
├──────────────┬──────────────┬──────────────┬────────────┤
│   Serviço    │  Banco de    │   Serviço    │ Runtime de │
│   de Auth    │   Dados      │ de Armaz.    │  Funções   │
│              │ (Firestore)  │              │            │
└──────────────┴──────────────┴──────────────┴────────────┘

Os SDKs do cliente abstraem a camada HTTP. Por baixo, cada operação se traduz em chamadas de API REST com autenticação JWT.

Autenticação Firebase: Configuração Completa

A autenticação é sua primeira integração com o Firebase. Se você errar isso, todo o resto falhará.

Passo 1: Criar Projeto Firebase

  1. Vá para o Console do Firebase

Clique em “Adicionar projeto” e Digite o nome do projeto (sem espaços)

Ative o Google Analytics (opcional, mas recomendado)

Clique em “Criar projeto”

Aguarde 30 segundos para o provisionamento. Você verá o painel do projeto.

Passo 2: Registrar Seu Aplicativo

Para Aplicativos Web:

// No Console do Firebase > Configurações do Projeto > Geral
// Clique em "Adicionar aplicativo" > Ícone da Web

// Registrar aplicativo web
const firebaseConfig = {
  apiKey: "AIzaSyDxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  authDomain: "seu-app.firebaseapp.com",
  projectId: "seu-app",
  storageBucket: "seu-app.appspot.com",
  messagingSenderId: "123456789012",
  appId: "1:123456789012:web:abc123def456"
};

// Inicializar Firebase
import { initializeApp } from 'firebase/app';
const app = initializeApp(firebaseConfig);

Para Aplicativos iOS:

Baixe GoogleService-Info.plist e adicione ao projeto Xcode. Certifique-se de que "Target Membership" inclua seu aplicativo.

Para Aplicativos Android:

Baixe google-services.json e coloque no diretório app/. Adicione ao build.gradle:

// build.gradle de nível de projeto
buildscript {
    dependencies {
        classpath 'com.google.gms:google-services:4.4.0'
    }
}

// build.gradle de nível de aplicativo
plugins {
    id 'com.google.gms.google-services'
}

Passo 3: Ativar Métodos de Autenticação

No Console do Firebase > Authentication > Método de login:

  1. E-mail/Senha: Ativar para registro tradicional
  2. Google: Adicione sua impressão digital do certificado SHA-1 (Android) ou ID do pacote (iOS)
  3. Apple: Necessário para aplicativos iOS se você ativar qualquer login social
  4. Telefone: Ativar para autenticação por SMS (requer faturamento)

Passo 4: Implementar o Fluxo de Autenticação

Cadastro com E-mail/Senha:

import {
  createUserWithEmailAndPassword,
  getAuth,
  updateProfile
} from 'firebase/auth';

const auth = getAuth(app);

async function signUp(email, password, displayName) {
  try {
    const userCredential = await createUserWithEmailAndPassword(
      auth,
      email,
      password
    );

    // Definir nome de exibição
    await updateProfile(userCredential.user, {
      displayName: displayName
    });

    console.log('Usuário criado:', userCredential.user.uid);
    return userCredential.user;
  } catch (error) {
    // Lidar com códigos de erro específicos
    switch (error.code) {
      case 'auth/email-already-in-use':
        throw new Error('Este e-mail já está registrado');
      case 'auth/weak-password':
        throw new Error('A senha deve ter pelo menos 6 caracteres');
      case 'auth/invalid-email':
        throw new Error('Endereço de e-mail inválido');
      default:
        throw new Error('Falha no cadastro: ' + error.message);
    }
  }
}

Login com E-mail/Senha:

import {
  signInWithEmailAndPassword,
  signOut
} from 'firebase/auth';

async function signIn(email, password) {
  try {
    const userCredential = await signInWithEmailAndPassword(
      auth,
      email,
      password
    );

    const user = userCredential.user;

    // Obter token de ID para chamadas de API
    const idToken = await user.getIdToken();
    console.log('Token de autenticação:', idToken);

    return user;
  } catch (error) {
    switch (error.code) {
      case 'auth/user-not-found':
        throw new Error('Nenhuma conta com este e-mail');
      case 'auth/wrong-password':
        throw new Error('Senha incorreta');
      case 'auth/too-many-requests':
        throw new Error('Muitas tentativas. Tente novamente mais tarde');
      default:
        throw new Error('Falha no login');
    }
  }
}

async function logOut() {
  await signOut(auth);
  console.log('Usuário desconectado');
}

Login com Google (Web):

import {
  GoogleAuthProvider,
  signInWithPopup
} from 'firebase/auth';

async function signInWithGoogle() {
  const provider = new GoogleAuthProvider();

  // Solicitar escopos adicionais
  provider.addScope('email');
  provider.addScope('profile');

  try {
    const result = await signInWithPopup(auth, provider);
    const user = result.user;

    // Acessar token OAuth do Google
    const credential = GoogleAuthProvider.credentialFromResult(result);
    const googleAccessToken = credential.accessToken;

    return user;
  } catch (error) {
    if (error.code === 'auth/popup-closed-by-user') {
      throw new Error('Login cancelado');
    }
    throw new Error('Falha no login com Google');
  }
}

Passo 5: Proteger Rotas com o Estado de Autenticação

import { onAuthStateChanged } from 'firebase/auth';

// Inscrever-se para alterações no estado de autenticação
onAuthStateChanged(auth, (user) => {
  if (user) {
    // Usuário está logado
    console.log('Usuário:', user.email);
    // Redirecionar para o painel
    window.location.href = '/dashboard';
  } else {
    // Usuário está desconectado
    console.log('Nenhum usuário');
    // Redirecionar para o login
    window.location.href = '/login';
  }
});

Erros Comuns de Autenticação

Erro 1: Não lidar com a atualização de token

O SDK do Firebase atualiza automaticamente os tokens. Mas se você armazenar tokens em cache no lado do servidor, eles expirarão após 1 hora. Sempre verifique os tokens em cada solicitação ou implemente uma lógica de atualização.

Erro 2: Expor credenciais de administrador no código do cliente

Nunca use chaves de conta de serviço em aplicativos cliente. As contas de serviço ignoram as regras de segurança. Use-as apenas em ambientes de servidor confiáveis.

Erro 3: Pular a verificação de e-mail

import { sendEmailVerification } from 'firebase/auth';

async function sendVerificationEmail(user) {
  await sendEmailVerification(user);
  console.log('E-mail de verificação enviado');
}

// Verificar status da verificação
if (!auth.currentUser.emailVerified) {
  console.log('E-mail não verificado');
  // Restringir acesso
}

Firestore Database: Operações e Consultas

Firestore é o banco de dados NoSQL do Firebase. Documentos são organizados em coleções. As consultas escalam automaticamente.

Estrutura de Dados

seu-projeto (raiz)
└── users (coleção)
    ├── userId123 (documento)
    │   ├── name: "John"
    │   ├── email: "john@example.com"
    │   └── posts (subcoleção)
    │       ├── postId1 (documento)
    │       └── postId2 (documento)
    └── userId456 (documento)

Inicializar Firestore

import { getFirestore } from 'firebase/firestore';

const db = getFirestore(app);

Criar Documentos

import {
  collection,
  addDoc,
  setDoc,
  doc
} from 'firebase/firestore';

// Opção 1: ID auto-gerado
async function createUser(userData) {
  const docRef = await addDoc(collection(db, 'users'), userData);
  console.log('Documento escrito com ID:', docRef.id);
  return docRef.id;
}

// Opção 2: ID personalizado
async function createUserWithId(userId, userData) {
  await setDoc(doc(db, 'users', userId), userData);
  console.log('Documento escrito com ID personalizado:', userId);
}

// Uso
const userId = await createUser({
  name: 'Alice',
  email: 'alice@example.com',
  createdAt: new Date(),
  role: 'user'
});

Ler Documentos

import {
  getDoc,
  getDocs,
  query,
  where,
  orderBy,
  limit
} from 'firebase/firestore';

// Obter documento único
async function getUser(userId) {
  const docRef = doc(db, 'users', userId);
  const docSnap = await getDoc(docRef);

  if (docSnap.exists()) {
    return docSnap.data();
  } else {
    throw new Error('Usuário não encontrado');
  }
}

// Consulta com filtros
async function getUsersByRole(role) {
  const q = query(
    collection(db, 'users'),
    where('role', '==', role),
    orderBy('createdAt', 'desc'),
    limit(10)
  );

  const querySnapshot = await getDocs(q);
  const users = [];

  querySnapshot.forEach((doc) => {
    users.push({ id: doc.id, ...doc.data() });
  });

  return users;
}

// Uso
const adminUsers = await getUsersByRole('admin');
console.log('Usuários administradores:', adminUsers);

Atualizar Documentos

import {
  updateDoc,
  increment,
  arrayUnion,
  arrayRemove
} from 'firebase/firestore';

async function updateUser(userId, updates) {
  const userRef = doc(db, 'users', userId);
  await updateDoc(userRef, updates);
}

// Operações atômicas
await updateUser('userId123', {
  loginCount: increment(1),
  tags: arrayUnion('premium', 'beta-tester'),
  lastLogin: new Date()
});

// Remover do array
await updateUser('userId123', {
  tags: arrayRemove('beta-tester')
});

Excluir Documentos

import { deleteDoc } from 'firebase/firestore';

async function deleteUser(userId) {
  await deleteDoc(doc(db, 'users', userId));
  console.log('Usuário excluído');
}

Listeners em Tempo Real

import { onSnapshot } from 'firebase/firestore';

// Escutar um único documento
const unsubscribe = onSnapshot(
  doc(db, 'users', userId),
  (doc) => {
    console.log('Usuário atualizado:', doc.data());
  },
  (error) => {
    console.error('Erro ao escutar:', error);
  }
);

// Escutar resultados de consulta
const q = query(collection(db, 'posts'), where('published', '==', true));

const unsubscribeQuery = onSnapshot(q, (snapshot) => {
  const posts = snapshot.docs.map(doc => ({
    id: doc.id,
    ...doc.data()
  }));
  console.log('Posts publicados:', posts);
});

// Parar de escutar
unsubscribe();
unsubscribeQuery();

Regras de Segurança do Firestore

Sem as regras adequadas, qualquer pessoa pode ler seus dados. Defina as regras no Console do Firebase > Firestore > Rules:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {

    // Função auxiliar
    function isAuthenticated() {
      return request.auth != null;
    }

    function isOwner(userId) {
      return request.auth.uid == userId;
    }

    // Coleção de usuários
    match /users/{userId} {
      allow read: if isAuthenticated();
      allow create: if isAuthenticated() && isOwner(userId);
      allow update, delete: if isOwner(userId);
    }

    // Coleção de posts
    match /posts/{postId} {
      allow read: if true; // Leitura pública
      allow create: if isAuthenticated();
      allow update, delete: if resource.data.authorId == request.auth.uid;
    }

    // Subcoleção privada
    match /users/{userId}/private/{document} {
      allow read, write: if isOwner(userId);
    }
  }
}

Limitações de Consulta

O Firestore tem restrições:

Solução alternativa para consultas OR:

// Em vez de: where('status', '==', 'active') OR where('status', '==', 'pending')

const activeQuery = query(
  collection(db, 'tasks'),
  where('status', '==', 'active')
);

const pendingQuery = query(
  collection(db, 'tasks'),
  where('status', '==', 'pending')
);

const [activeSnap, pendingSnap] = await Promise.all([
  getDocs(activeQuery),
  getDocs(pendingQuery)
]);

// Mesclar resultados no cliente

Cloud Functions: Lógica de Backend sem Servidor

Cloud Functions executam código de backend sem gerenciar servidores. Disparam em mudanças de banco de dados, requisições HTTP ou eventos agendados.

Configuração

# Instalar Firebase CLI
npm install -g firebase-tools

# Login
firebase login

# Inicializar funções em seu projeto
firebase init functions

# Selecione: JavaScript, ESLint sim, Express.js não

Funções HTTP (Endpoints de API)

// functions/index.js
const { onRequest } = require('firebase-functions/v2/https');
const admin = require('firebase-admin');

admin.initializeApp();
const db = admin.firestore();

// Endpoint público
exports.getPublicData = onRequest(async (req, res) => {
  res.set('Access-Control-Allow-Origin', '*');

  try {
    const snapshot = await db.collection('public').get();
    const data = snapshot.docs.map(doc => doc.data());
    res.json({ success: true, data });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// Endpoint protegido (verifica token de autenticação)
exports.getUserProfile = onRequest(async (req, res) => {
  res.set('Access-Control-Allow-Origin', '*');

  // Obter token do cabeçalho Authorization
  const authHeader = req.headers.authorization || '';
  const token = authHeader.split('Bearer ')[1];

  if (!token) {
    return res.status(401).json({ error: 'Não autorizado' });
  }

  try {
    // Verificar token
    const decodedToken = await admin.auth().verifyIdToken(token);
    const userId = decodedToken.uid;

    // Obter dados do usuário
    const userDoc = await db.collection('users').doc(userId).get();

    if (!userDoc.exists) {
      return res.status(404).json({ error: 'Usuário não encontrado' });
    }

    res.json({
      success: true,
      data: { id: userId, ...userDoc.data() }
    });
  } catch (error) {
    res.status(401).json({ error: 'Token inválido' });
  }
});

Implantar:

firebase deploy --only functions:getUserProfile

Chamar do cliente:

async function getUserProfile(token) {
  const response = await fetch(
    'https://us-central1-your-app.cloudfunctions.net/getUserProfile',
    {
      headers: {
        'Authorization': `Bearer ${token}`
      }
    }
  );

  const data = await response.json();
  return data;
}

Gatilhos de Banco de Dados

const { onDocumentWritten } = require('firebase-functions/v2/firestore');

// Disparar quando o documento do usuário muda
exports.onUserUpdate = onDocumentWritten(
  'users/{userId}',
  async (event) => {
    const userId = event.params.userId;
    const before = event.data?.before?.data();
    const after = event.data?.after?.data();

    // Verificar se o e-mail mudou
    if (before?.email !== after?.email) {
      console.log(`E-mail do usuário ${userId} mudou: ${before?.email} → ${after?.email}`);

      // Enviar e-mail de notificação
      await admin.auth().getUser(userId);
      // Adicione sua lógica de e-mail aqui
    }
  }
);

// Disparar na criação de um novo post
exports.onNewPost = onDocumentWritten(
  'posts/{postId}',
  async (event) => {
    const post = event.data?.after?.data();

    if (!post) return; // Documento excluído

    // Verificar se é um novo documento
    if (!event.data?.before?.exists) {
      console.log('Novo post criado:', post.title);

      // Notificar seguidores
      const followersSnap = await admin.firestore()
        .collection('users')
        .where('following', 'array-contains', post.authorId)
        .get();

      const notifications = followersSnap.docs.map(doc => ({
        userId: doc.id,
        postId: event.params.postId,
        type: 'new_post',
        createdAt: admin.firestore.FieldValue.serverTimestamp()
      }));

      const batch = admin.firestore().batch();
      notifications.forEach(notif => {
        const ref = admin.firestore().collection('notifications').doc();
        batch.set(ref, notif);
      });

      await batch.commit();
    }
  }
);

Funções Agendadas (Tarefas Cron)

const { onSchedule } = require('firebase-functions/v2/scheduler');

// Executar todo dia à meia-noite UTC
exports.dailyCleanup = onSchedule('every 24 hours', async (event) => {
  console.log('Executando limpeza diária');

  // Excluir notificações antigas (mais de 30 dias)
  const thirtyDaysAgo = new Date();
  thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);

  const oldNotifs = await admin.firestore()
    .collection('notifications')
    .where('createdAt', '<', thirtyDaysAgo)
    .get();

  const batch = admin.firestore().batch();
  oldNotifs.forEach(doc => batch.delete(doc.ref));
  await batch.commit();

  console.log(`Excluídas ${oldNotifs.size} notificações antigas`);
});

Configuração de Ambiente

# Definir variáveis de ambiente
firebase functions:config:set \
  stripe.secret="sk_test_xxx" \
  email.api_key="key_xxx"

# Acessar nas funções
const config = require('firebase-functions/config');
const stripe = require('stripe')(config.stripe.secret);

Cloud Storage: Upload e Gerenciamento de Arquivos

Armazene uploads de usuários, imagens e arquivos com distribuição CDN automática.

Configurar Regras de Armazenamento

// Console do Firebase > Storage > Regras
rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {

    // Pasta de uploads de usuários
    match /users/{userId}/{allPaths=**} {
      allow read: if true; // Leitura pública
      allow write: if request.auth.uid == userId;
      allow delete: if request.auth.uid == userId;
    }

    // Ativos públicos
    match /public/{allPaths=**} {
      allow read: if true;
      allow write: if false; // Somente Admin via Console do Firebase
    }
  }
}

Fazer Upload de Arquivos (Cliente)

import {
  getStorage,
  ref,
  uploadBytesResumable,
  getDownloadURL
} from 'firebase/storage';

const storage = getStorage(app);

async function uploadProfileImage(userId, file) {
  // Criar referência de armazenamento
  const storageRef = ref(storage, `users/${userId}/profile/${file.name}`);

  // Fazer upload do arquivo
  const uploadTask = uploadBytesResumable(storageRef, file);

  return new Promise((resolve, reject) => {
    uploadTask.on(
      'state_changed',
      (snapshot) => {
        // Acompanhar progresso
        const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
        console.log(`Upload: ${progress.toFixed(0)}%`);
      },
      (error) => {
        // Lidar com erros
        switch (error.code) {
          case 'storage/unauthorized':
            reject(new Error('Você não tem permissão'));
            break;
          case 'storage/canceled':
            reject(new Error('Upload cancelado'));
            break;
          default:
            reject(new Error('Falha no upload'));
        }
      },
      async () => {
        // Upload concluído
        const downloadURL = await getDownloadURL(uploadTask.snapshot.ref);
        console.log('Arquivo disponível em:', downloadURL);
        resolve(downloadURL);
      }
    );
  });
}

// Uso
const fileInput = document.querySelector('input[type="file"]');
const file = fileInput.files[0];

if (file) {
  const imageUrl = await uploadProfileImage(auth.currentUser.uid, file);

  // Salvar URL no Firestore
  await updateDoc(doc(db, 'users', auth.currentUser.uid), {
    profileImage: imageUrl
  });
}

Baixar Arquivos

import { getDownloadURL } from 'firebase/storage';

async function getProfileImage(userId) {
  const imageRef = ref(storage, `users/${userId}/profile/avatar.png`);

  try {
    const url = await getDownloadURL(imageRef);
    return url;
  } catch (error) {
    if (error.code === 'storage/object-not-found') {
      return null; // Nenhuma imagem de perfil
    }
    throw error;
  }
}

Excluir Arquivos

import { deleteObject } from 'firebase/storage';

async function deleteProfileImage(userId) {
  const imageRef = ref(storage, `users/${userId}/profile/avatar.png`);
  await deleteObject(imageRef);
  console.log('Imagem de perfil excluída');
}

Testando APIs Firebase com Apidog

O Firebase fornece APIs REST para todos os serviços. Testá-las diretamente ajuda a depurar problemas e a entender as requisições subjacentes.

Importar API REST do Firebase

  1. Abra o Apidog
  2. Crie um novo projeto: "Firebase API"
  3. Importe a especificação OpenAPI da documentação do Firebase
  4. Ou adicione endpoints manualmente:

Endpoint REST do Firestore:

POST https://firestore.googleapis.com/v1/projects/{projectId}/databases/(default)/documents
Authorization: Bearer {oauth2_token}
Content-Type: application/json

{
  "fields": {
    "name": { "stringValue": "John" },
    "email": { "stringValue": "john@example.com" },
    "age": { "integerValue": 30 }
  }
}

Endpoint de Autenticação:

POST https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key={api_key}
Content-Type: application/json

{
  "email": "user@example.com",
  "password": "secret123",
  "returnSecureToken": true
}

Testar Fluxo de Autenticação

  1. Crie a requisição: "Login"
  2. Defina o método: POST
  3. Adicione e-mail/senha no corpo
  4. Salve o token de resposta como variável de ambiente
  5. Use {{token}} nas requisições subsequentes

Depurar Regras de Segurança

Use a Firebase Emulator Suite para testes locais:

# Iniciar emulador
firebase emulators:start

# Testar contra Firestore local
# http://localhost:8080

Melhores Práticas em Produção

1. Implementar Tratamento de Erros Adequado

// Lógica de reintetativa para falhas transientes
async function firestoreWithRetry(operation, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await operation();
    } catch (error) {
      if (
        error.code === 'unavailable' ||
        error.code === 'deadline-exceeded'
      ) {
        const delay = Math.pow(2, i) * 1000; // Backoff exponencial
        await new Promise(resolve => setTimeout(resolve, delay));
        continue;
      }
      throw error;
    }
  }
}

2. Otimizar o Desempenho das Consultas

Adicione índices compostos para consultas multi-campo:

// Esta consulta precisa de um índice composto
const q = query(
  collection(db, 'posts'),
  where('category', '==', 'tech'),
  where('views', '>', 1000),
  orderBy('views', 'desc')
);

O Firestore o orientará a criar o índice com um link direto quando você executar esta consulta.

3. Operações em Lote

import { writeBatch } from 'firebase/firestore';

async function bulkUpdate(userIds, updates) {
  const batch = writeBatch(db);

  userIds.forEach(id => {
    const ref = doc(db, 'users', id);
    batch.update(ref, updates);
  });

  await batch.commit();
  console.log(`Atualizados ${userIds.length} usuários`);
}

// Máximo de 500 operações por lote

4. Monitorar Custos

Preços do Firebase:

Serviço Nível Gratuito Pago
Firestore 50K leituras/dia $0.036/100K leituras
Storage 5GB $0.023/GB
Functions 2M invocações $0.40/1M
Auth 10K/mês $0.0055/100K

Defina alertas de orçamento no Google Cloud Console.

5. Proteger Contas de Serviço

// ERRADO: Nunca faça isso no código do cliente
admin.initializeApp({
  credential: admin.credential.cert(require('./serviceAccountKey.json'))
});

// CORRETO: Use apenas em ambiente de servidor
const serviceAccount = JSON.parse(process.env.FIREBASE_SERVICE_ACCOUNT);
admin.initializeApp({
  credential: admin.credential.cert(serviceAccount)
});

6. Lidar com Cenários Offline

// Ativar persistência offline (web)
import { enableMultiTabIndexedDbPersistence } from 'firebase/firestore';

enableMultiTabIndexedDbPersistence(db)
  .catch((err) => {
    if (err.code === 'failed-precondition') {
      // Múltiplas abas abertas
    } else if (err.code === 'unimplemented') {
      // Navegador não suporta
    }
  });

// Escutar conectividade
import { onSnapshot } from 'firebase/firestore';

onSnapshot(doc(db, 'status', 'online'), (doc) => {
  if (!doc.exists()) {
    console.log('Você está offline');
    // Mostrar UI offline
  }
});

Problemas Comuns da API Firebase e Soluções

Problema 1: Erros de Permissão Negada

Sintoma: Error: 7 PERMISSION_DENIED

Causa: As regras de segurança bloqueiam a operação

Correção:

  1. Verifique as regras no Console do Firebase
  2. Verifique se request.auth.uid corresponde ao usuário esperado
  3. Teste as regras com o Rules Playground

Problema 2: Expiração de Token

Sintoma: Error: ID token expired

Correção:

// Forçar atualização de token
const user = auth.currentUser;
if (user) {
  await user.getIdToken(true); // Forçar atualização
}

Problema 3: Latência de Cold Start

Sintoma: Cloud Functions levam de 2 a 5 segundos na primeira chamada

Correção:

// Manter as funções "quentes" com pings agendados
exports.keepWarm = onSchedule('every 60 seconds', async () => {
  await fetch('https://your-function.cloudfunctions.net/health');
});

Problema 4: Consulta Retorna Resultados Vazios

Sintoma: A consulta deveria retornar dados, mas retorna um array vazio

Causa: Índice ausente ou ordem de campo incorreta

Correção: Verifique o Console do Firestore > Índices para os índices compostos necessários.

Casos de Uso no Mundo Real

App Fintech: Atualizações de Transações em Tempo Real

Uma startup de pagamentos usou o Firebase Firestore para criar notificações de transações em tempo real. Quando um pagamento é processado, o Cloud Functions aciona atualizações para todos os painéis administrativos conectados em 200ms. Resultado: 40% de redução nos tickets de suporte sobre transações "pendentes".

E-commerce: Sincronização de Estoque

Um varejista online sincroniza o estoque em web, iOS e Android usando listeners do Firestore. Quando o estoque muda, todos os clientes são atualizados automaticamente. A persistência offline garante que os trabalhadores do armazém possam escanear itens sem conectividade, com sincronização automática quando reconectados.

SaaS: Autenticação Multi-Tenant

Uma plataforma B2B usa Firebase Auth com custom claims para acesso baseado em funções. Usuários administradores obtêm permissões elevadas via Cloud Functions que validam contra as configurações de tenant do Firestore. Uma única base de código atende mais de 500 organizações com dados isolados.

Conclusão

A integração da API Firebase envolve quatro serviços principais:

Você aprendeu fluxos de autenticação, operações de banco de dados, implantação de funções e gerenciamento de arquivos. Você viu padrões de produção: tratamento de erros, processamento em lote, suporte offline e segurança.

button

FAQ

O Firebase é gratuito?

Sim, o Firebase possui um generoso nível gratuito (Plano Spark) incluindo 5GB de armazenamento, 50K leituras do Firestore por dia, 2M invocações de Cloud Functions e 10K usuários de Auth por mês. Planos pagos (Blaze) usam preços de pagamento conforme o uso.

Posso usar o Firebase com bancos de dados existentes?

Sim. Use as Extensões do Firebase para sincronizar com PostgreSQL, MySQL ou MongoDB. Ou chame APIs externas do Cloud Functions para integrar com sistemas existentes.

Como migro do Firebase para outra plataforma?

Exporte dados usando as funções de exportação do Firestore ou o Firebase CLI. Para grandes conjuntos de dados, use o pipeline de exportação do Dataflow. A complexidade da migração depende da estrutura dos seus dados.

O Firebase suporta GraphQL?

Não nativamente. Use soluções de terceiros como firestore-graphql ou construa uma camada GraphQL com Cloud Functions e Apollo Server.

Posso usar o Firebase localmente?

Não. O Firebase é exclusivamente Google Cloud. Para alternativas auto-hospedadas, considere Appwrite, Supabase ou Nhost.

Como lidar com uploads de arquivos maiores que 100MB?

Use uploads resumíveis com fragmentação (chunking). O SDK do Firebase lida com isso automaticamente. Para arquivos muito grandes, use o Google Cloud Storage diretamente com URLs assinadas.

O que acontece se eu exceder os limites de consulta do Firestore?

As consultas falham com o erro FAILED_PRECONDITION. Adicione os índices necessários ou reestruture as consultas. O Firestore fornece links diretos para criar índices ausentes na mensagem de erro.

O Firebase está em conformidade com o GDPR?

Sim, o Firebase oferece processamento de dados em conformidade com o GDPR. Habilite a residência de dados em regiões específicas, implemente a exportação/exclusão de dados do usuário e assine o Adendo de Processamento de Dados do Google.

Pratique o design de API no Apidog

Descubra uma forma mais fácil de construir e usar APIs