# Como consumir API de CPF em Firebase Functions para backend serverless

> Aprenda a criar Firebase Functions que consultam CPF via API CPFHub.io com TypeScript, Firestore para cache e integração com Firebase Auth.

**Publicado:** 07/10/2026
**Autor:** Lucas Vieira
**URL:** https://www.cpfhub.io/blog/como-consumir-api-cpf-firebase-functions-backend-serverless

---


Para integrar a API de CPF da CPFHub.io em um backend serverless com Firebase, você cria uma Firebase Function que faz uma chamada GET autenticada para `https://api.cpfhub.io/cpf/{CPF}` e armazena o resultado no Firestore como cache. A latência típica da API é de ~150 ms, por isso o cache no Firestore é indispensável para manter o tempo de resposta aceitável em produção. O deploy na região `southamerica-east1` garante a menor latência possível para usuários brasileiros.

Firebase e a plataforma de desenvolvimento de aplicações do Google que oferece um ecossistema completo: autenticação, banco de dados em tempo real, hosting, storage e Cloud Functions. As Firebase Functions (baseadas no Google Cloud Functions) permitem executar código backend em resposta a eventos HTTP, alteracoes no Firestore ou gatilhos de autenticação -- tudo sem gerenciar servidores.

Para aplicações que utilizam Firebase como backend -- apps mobile, SPAs e plataformas web -- as Firebase Functions são a forma natural de integrar a API da [**CPFHub.io**](https://www.cpfhub.io/)

## Configuração do projeto

Inicialize o projeto Firebase com Functions:

```bash
# Instalar Firebase CLI
npm install -g firebase-tools

# Login
firebase login

# Inicializar Functions
firebase init functions

# Selecione:
# - TypeScript
# - ESLint: Sim
# - Instalar dependencias: Sim
```

Estrutura resultante:

```
functions/
 src/
 index.ts
 package.json
 tsconfig.json
```

---

## Serviço de consulta de CPF

Crie o módulo que encapsula a comunicação com a API:

```typescript
// functions/src/services/cpfhub.ts
import { defineString } from "firebase-functions/params";

const cpfhubApiKey = defineString("CPFHUB_API_KEY");

const API_URL = "https://api.cpfhub.io/cpf";
const TIMEOUT_MS = 10000;

interface CPFData {
 cpf: string;
 name: string;
 nameUpper: string;
 gender: string;
 birthDate: string;
 day: number;
 month: number;
 year: number;
}

interface CPFApiResponse {
 success: boolean;
 data?: CPFData;
}

export interface ConsultaResultado {
 sucesso: boolean;
 dados?: {
 cpf: string;
 nome: string;
 genero: string;
 dataNascimento: string;
 dia: number;
 mes: number;
 ano: number;
 };
 erro?: string;
}

export async function consultarCPF(cpf: string): Promise<ConsultaResultado> {
 const cpfLimpo = cpf.replace(/\D/g, "");

 if (cpfLimpo.length !== 11) {
 return { sucesso: false, erro: "CPF deve conter 11 digitos" };
 }

 if (/^(\d)\1+$/.test(cpfLimpo)) {
 return { sucesso: false, erro: "CPF invalido" };
 }

 const controller = new AbortController();
 const timeoutId = setTimeout(() => controller.abort(), TIMEOUT_MS);

 try {
 const response = await fetch(`${API_URL}/${cpfLimpo}`, {
 method: "GET",
 headers: {
 "x-api-key": cpfhubApiKey.value(),
 "Accept": "application/json",
 },
 signal: controller.signal,
 });

 clearTimeout(timeoutId);

 if (!response.ok) {
 return { sucesso: false, erro: `Erro HTTP ${response.status}` };
 }

 const resultado: CPFApiResponse = await response.json();

 if (!resultado.success || !resultado.data) {
 return { sucesso: false, erro: "CPF nao encontrado" };
 }

 return {
 sucesso: true,
 dados: {
 cpf: resultado.data.cpf,
 nome: resultado.data.name,
 genero: resultado.data.gender,
 dataNascimento: resultado.data.birthDate,
 dia: resultado.data.day,
 mes: resultado.data.month,
 ano: resultado.data.year,
 },
 };
 } catch (error) {
 clearTimeout(timeoutId);

 if (error instanceof Error && error.name === "AbortError") {
 return { sucesso: false, erro: "Timeout na consulta" };
 }

 return { sucesso: false, erro: `Erro: ${String(error)}` };
 }
}
```

O `defineString` do Firebase Functions v2 permite definir parametros de configuração que são solicitados no deploy.

---

## Função HTTP para validação

A função HTTP e o ponto de entrada para consultas via API REST:

```typescript
// functions/src/index.ts
import { onRequest } from "firebase-functions/v2/https";
import { onDocumentCreated } from "firebase-functions/v2/firestore";
import { getFirestore, FieldValue } from "firebase-admin/firestore";
import { initializeApp } from "firebase-admin/app";
import { consultarCPF } from "./services/cpfhub";

initializeApp();
const db = getFirestore();

const CACHE_COLLECTION = "cpf_cache";
const CACHE_TTL_HOURS = 24;

export const validarCpf = onRequest(
 {
 region: "southamerica-east1",
 cors: true,
 maxInstances: 10,
 },
 async (req, res) => {
 if (req.method !== "GET") {
 res.status(405).json({ erro: "Use GET" });
 return;
 }

 const cpf = req.query.cpf as string || req.params[0];

 if (!cpf) {
 res.status(400).json({ erro: "CPF e obrigatorio" });
 return;
 }

 const cpfLimpo = cpf.replace(/\D/g, "");

 // Verificar cache no Firestore
 const cacheDoc = await db
 .collection(CACHE_COLLECTION)
 .doc(cpfLimpo)
 .get();

 if (cacheDoc.exists) {
 const cacheData = cacheDoc.data();
 const expiraEm = cacheData?.expiraEm?.toDate();

 if (expiraEm && expiraEm > new Date()) {
 res.json({
 valido: true,
 dados: cacheData?.dados,
 fonte: "cache",
 });
 return;
 }
 }

 // Consultar API
 const resultado = await consultarCPF(cpfLimpo);

 if (!resultado.sucesso) {
 const status = resultado.erro?.includes("nao encontrado") ? 404 : 500;
 res.status(status).json({ erro: resultado.erro });
 return;
 }

 // Salvar no cache
 const expiraEm = new Date();
 expiraEm.setHours(expiraEm.getHours() + CACHE_TTL_HOURS);

 await db.collection(CACHE_COLLECTION).doc(cpfLimpo).set({
 dados: resultado.dados,
 expiraEm,
 criadoEm: FieldValue.serverTimestamp(),
 });

 res.json({
 valido: true,
 dados: resultado.dados,
 fonte: "api",
 });
 }
);
```

---

## Função acionada por evento do Firestore

Valide CPF automaticamente quando um novo documento e criado no Firestore:

```typescript
// functions/src/index.ts (continuacao)

export const validarCpfNoCadastro = onDocumentCreated(
 {
 document: "cadastros/{docId}",
 region: "southamerica-east1",
 },
 async (event) => {
 const snapshot = event.data;

 if (!snapshot) {
 console.log("Documento vazio");
 return;
 }

 const dados = snapshot.data();
 const cpf = dados.cpf;

 if (!cpf) {
 console.log("CPF nao informado no documento");
 return;
 }

 const resultado = await consultarCPF(cpf);

 const atualizacao: Record<string, unknown> = {
 cpfValidadoEm: FieldValue.serverTimestamp(),
 };

 if (resultado.sucesso) {
 atualizacao.cpfStatus = "validado";
 atualizacao.cpfNomeValidado = resultado.dados?.nome;
 atualizacao.cpfGenero = resultado.dados?.genero;
 atualizacao.cpfDataNascimento = resultado.dados?.dataNascimento;

 // Verificar se o nome confere
 const nomeInformado = (dados.nome || "").toUpperCase().split(" ")[0];
 const nomeAPI = (resultado.dados?.nome || "").toUpperCase().split(" ")[0];

 if (nomeInformado && nomeAPI && nomeInformado !== nomeAPI) {
 atualizacao.cpfStatus = "divergente";
 atualizacao.cpfAlerta = "Nome informado diverge do CPF";
 }
 } else {
 atualizacao.cpfStatus = "invalido";
 atualizacao.cpfErro = resultado.erro;
 }

 await snapshot.ref.update(atualizacao);
 console.log(`CPF ${cpf} validado: ${atualizacao.cpfStatus}`);
 }
);
```

Com esse trigger, qualquer documento adicionado a coleção `cadastros` no Firestore tera o CPF validado automaticamente.

---

## Callable Function para apps Flutter e React Native

Firebase Callable Functions são a forma recomendada de chamar funções a partir de apps mobile:

```typescript
// functions/src/index.ts (continuacao)
import { onCall, HttpsError } from "firebase-functions/v2/https";

export const consultarCpfCallable = onCall(
 {
 region: "southamerica-east1",
 maxInstances: 10,
 },
 async (request) => {
 // Verificar autenticacao
 if (!request.auth) {
 throw new HttpsError(
 "unauthenticated",
 "Usuario nao autenticado"
 );
 }

 const cpf = request.data.cpf;

 if (!cpf) {
 throw new HttpsError(
 "invalid-argument",
 "CPF e obrigatorio"
 );
 }

 const resultado = await consultarCPF(cpf);

 if (!resultado.sucesso) {
 throw new HttpsError(
 "not-found",
 resultado.erro ?? "CPF nao encontrado"
 );
 }

 return resultado.dados;
 }
);
```

No app mobile (JavaScript/React Native):

```typescript
import { getFunctions, httpsCallable } from "firebase/functions";

const functions = getFunctions(app, "southamerica-east1");
const consultarCPF = httpsCallable(functions, "consultarCpfCallable");

async function validar(cpf: string) {
 try {
 const result = await consultarCPF({ cpf });
 console.log("Dados:", result.data);
 } catch (error) {
 console.error("Erro:", error);
 }
}
```

---

## Configuração de segredos

Configure a chave de API como parametro do Firebase:

```bash
# Definir parametro
firebase functions:secrets:set CPFHUB_API_KEY

# Verificar
firebase functions:secrets:access CPFHUB_API_KEY
```

---

## Deploy e teste

```bash
# Deploy de todas as funcoes
firebase deploy --only functions

# Deploy de funcao especifica
firebase deploy --only functions:validarCpf

# Testar localmente
firebase emulators:start --only functions,firestore
```

Teste local com curl:

```bash
curl "http://localhost:5001/meu-projeto/southamerica-east1/validarCpf?cpf=12345678901"
```

---

## Limpeza de cache com Scheduled Function

Crie uma função agendada para limpar cache expirado:

```typescript
import { onSchedule } from "firebase-functions/v2/scheduler";

export const limparCacheCPF = onSchedule(
 {
 schedule: "every 24 hours",
 region: "southamerica-east1",
 },
 async () => {
 const agora = new Date();
 const snapshot = await db
 .collection(CACHE_COLLECTION)
 .where("expiraEm", "<", agora)
 .limit(500)
 .get();

 const batch = db.batch();
 snapshot.docs.forEach((doc) => batch.delete(doc.ref));
 await batch.commit();

 console.log(`${snapshot.size} registros de cache removidos`);
 }
);
```

---

## Perguntas frequentes

### Por que usar o Firestore como cache para chamadas à API de CPF em Firebase Functions?

A API de CPF tem latência de ~150 ms por consulta. Sem cache, cada validação bloqueia a Function pelo tempo de ida e volta da requisição, aumentando o custo de execução (Firebase Functions cobra por tempo de CPU) e prejudicando a experiência do usuário. O Firestore como cache reduz chamadas repetidas ao mesmo CPF e mantém os dados disponíveis entre cold starts de Function.

### O que acontece se o limite do plano gratuito for atingido durante a execução das Functions?

A cota mensal e o limite por minuto não se confundem. No plano Grátis, zerar os 50 créditos pausa as consultas com HTTP 403 ("Limite de créditos excedido"); nos planos pagos, o excedente eventual é faturado depois, no preço da [página de preços](https://www.cpfhub.io/precos). Acima do limite por minuto a API responde HTTP 429 e informa o Retry-After. Para ambientes de produção com volume previsível, o plano Pro (R$149/mês, 1.000 consultas) é mais adequado.

### Como proteger a chave de API da CPFHub.io em Firebase Functions?

Use `firebase functions:secrets:set CPFHUB_API_KEY` para armazenar a chave no Secret Manager do Google Cloud, que é o mecanismo nativo do Firebase Functions v2 para segredos. Nunca hardcode a chave no código-fonte nem a coloque em variáveis de ambiente não criptografadas. Consulte a [documentação oficial do Firebase](https://firebase.google.com/docs/functions/config-env) para boas práticas de configuração.

### Como lidar com timeouts e falhas de rede nas chamadas à API dentro das Functions?

Configure `AbortController` com timeout de 10 segundos (como no exemplo acima) e implemente retry com backoff exponencial para falhas transitórias. O [OWASP](https://owasp.org) recomenda que integrações com APIs externas sempre tenham timeout definido e tratamento explícito de erros de rede para evitar que a Function fique pendurada até o limite máximo de execução.

### Leia também

- [Como implementar cache inteligente em respostas de API de CPF](https://cpfhub.io/blog/como-implementar-cache-inteligente-respostas-api-cpf)
- [SLA de API de CPF: níveis de disponibilidade](https://cpfhub.io/blog/sla-api-cpf-niveis-disponibilidade)
- [API de CPF grátis para desenvolvedores: como começar em 5 minutos](https://cpfhub.io/blog/api-cpf-gratis-desenvolvedores-comecar-5-minutos)
- [KYC no Brasil: quais setores são obrigados a validar CPF por lei](https://cpfhub.io/blog/kyc-no-brasil-quais-setores-sao-obrigados-a-validar-cpf-por-lei)

---

## Conclusão

Firebase Functions oferecem uma integração natural com o ecossistema Firebase para validação de CPF. Funções HTTP para APIs REST, triggers do Firestore para validação automática e Callable Functions para apps mobile criam uma solução completa. O Firestore serve como cache distribuido, e a regiao `southamerica-east1` garante a menor latência para usuários brasileiros. A API da [**CPFHub.io**](https://www.cpfhub.io/)

Cadastre-se em [cpfhub.io](https://www.cpfhub.io/)

