javascriptangularfirebasegoogle-cloud-firestoreangularfire

Strange behavior in AngularFire


I refer to this document to learn AngularFire and works very well in Angular Component.
If I try to move to custom class(FirestoreService please take a look) will occur errors.

FirebaseError: [code=invalid-argument]: Expected first argument to collection() to be a CollectionReference, a DocumentReference or FirebaseFirestore

Do I forget something?

version

"@angular/animations": "^18.0.0",
"@angular/cdk": "^18.0.1",
"@angular/common": "^18.0.0",
"@angular/compiler": "^18.0.0",
"@angular/core": "^18.0.0",
"@angular/fire": "^18.0.1",
"@angular/forms": "^18.0.0",
"@angular/material": "^18.0.1",
"@angular/platform-browser": "^18.0.0",
"@angular/platform-browser-dynamic": "^18.0.0",
"@angular/router": "^18.0.0",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.14.3"

app.config.ts

export const appConfig: ApplicationConfig = {
    providers: [
        provideZoneChangeDetection({ eventCoalescing: true }),
        provideAnimationsAsync(),
        provideFirebaseApp(() => initializeApp(environment.firebase)),
        provideAuth(() => getAuth()),
        provideFirestore(() => getFirestore()),
    ]
};

items.component.ts

export class ItemsComponent {
    items: Item[] = [];

    constructor(private firestoreService: FirestoreService) {
        firestoreService.items$.subscribe(items => {
            this.items = items;
        });
    }

firestore.service.ts

import { Firestore, collectionData, collection } from '@angular/fire/firestore';

@Injectable({
    providedIn: 'root'
})
export class FirestoreService {
    items$: Observable<Item[]>;
    private firestore: Firestore = Inject(Firestore);

    constructor() {
        const itemCollection = collection(this.firestore, 'items');
        this.items$ = collectionData<Item>(itemCollection);
    }
}

Solution

  • I am not sure if this is the problem, but you should use inject instead of Inject from @anuglar/core.

    import { Firestore, collectionData, collection } from '@angular/fire/firestore';
    
    @Injectable({
        providedIn: 'root'
    })
    export class FirestoreService {
        items$: Observable<Item[]>;
        private firestore: Firestore = inject(Firestore); // <- changed here!
    
        constructor() {
            const itemCollection = collection(this.firestore, 'items');
            this.items$ = collectionData<Item>(itemCollection);
        }
    }