Ao atualizar para o Angular 21 e tentar utilizar o SDK modular do Firebase (firebase/firestore), é comum se deparar com erros de “Provedor não encontrado” ou conflitos de tipos internos. Neste artigo, vamos dissecar a causa desses erros e como resolvê-los usando as melhores práticas atuais.
1. O Erro de Provedor: NG0201 Link para o cabeçalho
Mensagem:
ERROR ɵNotFound: NG0201: No provider found for Firestore
A Causa Link para o cabeçalho
Desde o Angular 17, a arquitetura padrão é Standalone. Isso significa que não existe mais o app.module.ts. Se você tenta usar o inject(Firestore) em um componente, mas não registrou o serviço no bootstrap da aplicação, o Angular não sabe como instanciá-lo.
A Solução Link para o cabeçalho
Você deve configurar os provedores no arquivo app.config.ts. Certifique-se de importar as funções de inicialização do @angular/fire.
// src/app/app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideFirebaseApp, initializeApp } from '@angular/fire/app';
import { provideFirestore, getFirestore } from '@angular/fire/firestore';
import { environment } from '../environments/environment';
export const appConfig: ApplicationConfig = {
providers: [
// Ordem crucial: primeiro inicializa o App, depois os serviços
provideFirebaseApp(() => initializeApp(environment.firebase)),
provideFirestore(() => getFirestore()),
]
};
Certifique-se de que no main.ts, o bootstrapApplication(App, appConfig) está recebendo este objeto de configuração.
2. O Conflito de Tipos: _Query vs _CollectionReference Link para o cabeçalho
Mensagem:
ERROR FirebaseError: Expected type '_Query', but it was: a custom _CollectionReference object
A Causa Link para o cabeçalho
Este é o erro mais frustrante. Ele ocorre quando há uma “mismatch” (descompasso) de instâncias:
-
Você injeta o
Firestoreatravés do@angular/fire. -
Você tenta passar esse objeto injetado para funções (como
query,collection,getDocs) importadas diretamente defirebase/firestore(o SDK puro).
Internamente, o @angular/fire envolve o Firestore em um wrapper. O SDK puro não reconhece esse wrapper como uma instância válida, lançando o erro de tipo.
A Solução Definitiva Link para o cabeçalho
Para manter a sintaxe modular (Promises/async-await) que você deseja, a regra de ouro é: Importe as funções operacionais do @angular/fire/firestore, mas mantenha a lógica de execução.
As funções exportadas pelo @angular/fire/firestore possuem a mesma assinatura do SDK puro, mas são cientes do sistema de injeção do Angular.
O Código Final (Boa Prática) Link para o cabeçalho
Aqui está como o componente deve ficar para evitar ambos os erros, utilizando Signals para performance:
import { Component, inject, OnInit, signal } from '@angular/core';
import { JsonPipe } from '@angular/common';
// SOLUÇÃO: Importe as funções do wrapper do AngularFire
import {
Firestore,
collection,
query,
getDocs
} from '@angular/fire/firestore';
@Component({
selector: 'app-root',
standalone: true,
imports: [JsonPipe],
//templateUrl: './app.html',
//styleUrl: './app.css'
template: `
@for (item of dados(); track item.id) {
<p>{{ item.nome }}</p>
}
`
})
export class App implements OnInit {
// Injeção limpa e segura
private readonly db: Firestore = inject(Firestore);
// Estado reativo com Signals
protected dados = signal<any[]>([]);
async ngOnInit() {
await this.fetchFirestoreData();
}
async fetchFirestoreData() {
try {
const colecaoRef = collection(this.db, 'sua-colecao');
const q = query(colecaoRef);
// Uso de async/await perfeitamente compatível
const querySnapshot = await getDocs(q);
const results = querySnapshot.docs.map(doc => ({
id: doc.id,
...doc.data()
}));
this.dados.set(results);
} catch (e) {
console.error("Erro na busca:", e);
}
}
}
Resumo para o desenvolvedor Link para o cabeçalho
-
NG0201? Verifique se o
provideFirestore()está noapp.config.ts. -
_Query mismatch? Pare de importar de
firebase/firestoree passe a importar de@angular/fire/firestore. -
Template parou de atualizar? Troque variáveis comuns por
Signalspara garantir que o Angular detecte a mudança após oawait.