angular / angularfire

Angular + Firebase = ❤️
https://firebaseopensource.com/projects/angular/angularfire2
MIT License
7.64k stars 2.2k forks source link

Use multiple firestore databases #3450

Open rubenheymans opened 8 months ago

rubenheymans commented 8 months ago

Version info

Angular: 16.2.9

Firebase: 9.23.0

AngularFire: 7.6.1

We can now create multiple firestore databases. The documentation mentions we can access a named database with a client library, how do we do this in AngularFire? https://cloud.google.com/firestore/docs/manage-databases#access_a_named_database_with_a_client_library

Can we add a new option to firebaseConfig?

 production: false,
  environment: 'dev',
  firebaseConfig: {
    apiKey: '',
    authDomain: '',
    databaseURL: '',
    projectId: '',
    storageBucket: '',
    messagingSenderId: '',
    appId: '',
    extraOptionHere??
  },
  useEmulators: true,
  origin: undefined,
google-oss-bot commented 8 months ago

This issue does not seem to follow the issue template. Make sure you provide all the required information.

jamesdaniels commented 8 months ago

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 1) 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. 1) 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.

chumberjosh commented 8 months ago

@jamesdaniels is there any way of doing it by importing modules? Like shown here https://stackoverflow.com/questions/77377149/how-to-access-non-default-firestore-database-in-angularfire

jamesdaniels commented 8 months ago

@chumberjosh I don't believe there's a compat API to be able to access these. You will need to get/initializeFirestore with the modular API to setup access. That said you should be able to mix and match the modular and compat APIs as needed, just means a little work to migrate your code.

omar-dev-amrk commented 7 months ago

Hey @jamesdaniels Could you show a code example please?

I'm on v7.5

omar-dev-amrk commented 7 months ago

I have this code so far:

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 both the default and second instances are getting logged. But instance field does not provide Firestore fields like collection and others:

image

What should I do to surface them?

omar-dev-amrk commented 7 months ago

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")
      )
    );
  }
}
maev-mcbo commented 3 months ago

how i would reference a differente db ? i think im missing something, because in getUsers() how i would tell that i want form a specific db?