Search code examples
angulargoogle-cloud-firestoreangularfire2

How to connect to a second database using Angular Fire?


I have this code:

import { FirebaseApp } from "@angular/fire/compat";
import {
  AngularFirestore
} from "@angular/fire/compat//firestore";

import {
  initializeFirestore
} from "@angular/fire/firestore";

import { firestoreInstance$ } from "@angular/fire/firestore";

export class AppModule {
  constructor(private firestore: AngularFirestore) {
    const firebaseApp: FirebaseApp = this.firestore.firestore.app;

    initializeFirestore(firebaseApp, {}, secondDbName);

    firestoreInstance$.subscribe((instance) => {
      console.log("instance:", instance);
    });
  }
}

And been trying to get a proper firestore instance of a non-default database. I followed the suggestions mentioned by the repo:

In theory there are three APIs that should allow this in the new API:

  1. You should be able to inject FirestoreInstances into your component to get an array of the firestore instances. They would have had to have been initialized before your component.

  2. There's an observable, firestoreInstance$ which you can import from @angular/fire/firestore, you can filter the observable emissions to grab the database you want.

  3. You can use the same API as you would the JS SDK to get access (getFirestore and initializeFirestore, see the databaseId arg), just import from @angular/fire/firestore rather than firebase/firestore so you get Zone.js fixes.

That said, we only unblocked use against Firebase JS SDK v10 the other day with the release of AngularFire v16. So I've not had a chance to experiment here yet.

instance above gets logged multiple times, one of which is the database I need. But, the shape of the object only has three keys:

app, toJSON and type

code preview

Using: Angular 15 + Angular Fire 7.5


Solution

  • Eventually, I rewrote all queries I have to use the modular syntax, and refactored away from all things compat. Here's how you make your code connected to any database in the same project:

    
    import { getApp, initializeApp, provideFirebaseApp } from "@angular/fire/app";
    import { initializeFirestore, provideFirestore } from "@angular/fire/firestore";
    
    @NgModule({
      imports: [
        provideFirebaseApp(() => initializeApp(config)),
        provideFirestore(() => {
          const app = getApp();
          const dbName = "db-name";
          const providedFirestore = initializeFirestore(app, {}, dbName);
          return providedFirestore;
        }),
      ]
    })
    

    Then in your services:

    import { inject } from "@angular/core";
    import { Firestore, getDocs } from "@angular/fire/firestore";
    import {
      collection,
      query,
      where,
      orderBy,
    } from "@angular/fire/firestore";
    
    @Injectable({
      providedIn: "root",
    })
    export class MyService {
      private firestore: Firestore = inject(Firestore);
    
      getUsers() {
        return getDocs(
          query(
            collection(this.firestore, "Users"),
            where("some_id", "==", "id"),
            orderBy("created_at", "asc")
          )
        );
      }
    }
    

    This also can let you connect to multiple databases and inject them as needed.