Skip to content

Query: Multiple database support. #761

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
sudharsanmit opened this issue Jan 6, 2017 · 17 comments
Closed

Query: Multiple database support. #761

sudharsanmit opened this issue Jan 6, 2017 · 17 comments

Comments

@sudharsanmit
Copy link

Does Angularfire2 support multiple firebase projects? If so, how to implement it? I read about it in the below googleblog.

https://firebase.googleblog.com/2016/12/working-with-multiple-firebase-projects-in-an-android-app.html

@davideast
Copy link
Collaborator

davideast commented Jan 11, 2017

@sudharsanmit You can create a new app and pass in the reference.

const app = firebase.initializeApp({ ... });
const ref = app.database().ref('items');
const listObs = af.database.list(ref);

@sudharsanmit
Copy link
Author

image

I am not able to get it to work. Method ref is not existing on app.database.

@katowulf
Copy link
Contributor

Try app.database().ref() instead.

@sudharsanmit
Copy link
Author

Thanks @katowulf . I got it working!

    init(config){
        const app = firebase.initializeApp(config,"secondary");
        const ref = app.database().ref('/test');
        const listObs = this.af.database.object(ref);
        listObs.subscribe(data => console.log(data));
    }

@chetanbnaik
Copy link

Please share a detailed code on how to implement the multiple database through angularfire

@daimz
Copy link

daimz commented Aug 23, 2017

@sudharsanmit Are you able to please share a more detailed example of how you got this working, I am currently trying to do the same but unclear on how to set it up correctly.

@sudharsanmit
Copy link
Author

sudharsanmit commented Aug 23, 2017

@daimz @chetanbnaik

Service :

import {Injectable,Inject} from '@angular/core';
import { AngularFireModule,AngularFire, AngularFireAuth, AngularFireDatabase } from 'angularfire2';


@Injectable()
export class secondaryDB {
	secondary:any;
	constructor (private af:AngularFire){

	}

    init(config){
        const app = firebase.initializeApp(config,"secondary");
        const ref = app.database().ref('/test');
        const listObs = this.af.database.object(ref);
        listObs.subscribe(data => console.log(data));
    }
}

Controller:

import {secondaryDB} from '../../app/secondaryDB.service';
--other imports--

@Component({
  templateUrl: 'test.html'
})
export class TestPage {
  constructor(private secDB:secondaryDB) {

  var config = {
    apiKey: "XXXXXX",
    authDomain: "XXXX.firebaseapp.com",
    databaseURL: "https://XXXX.firebaseio.com",
    storageBucket: "project-XXXX.appspot.com",
    messagingSenderId: "XXXX"
   };    
    secDB.init(config);
  }
}

@daimz
Copy link

daimz commented Aug 24, 2017

Thanks for that @sudharsanmit really helpful!

@daimz
Copy link

daimz commented Aug 26, 2017

@sudharsanmit I am using the method you suggested above, but I am running into an error and wondering if you could help me with it.
I have created the service as you suggested but I now have to services a cohort.service and a team.service in both services I am needed to access my secondary database so I have included the CoreDB.service and then initiated in both services. This returns the following error

FirebaseError {code: "app/duplicate-app", message: "Firebase: Firebase App named 'core' already exists (app/duplicate-app).", name: "core", ngDebugContext: DebugContext_, ngErrorLogger: ƒ, …}

I realise this is because I am now attempting to initialise my secondary database twice. How can I do this at a root level or similar so that it is only initiated once but available to all my services?

Here's what my code looks like:
teams.service

export class TeamsService {
  private sdkDb;
  private app;
  private teamsRef;

  constructor(
    private db: AngularFireDatabase,
    private coreDB: CoreDBService
  ) {
    coreDB.init(environment.fbCoreConfig);
    console.log(coreDB.app);
    const ref = coreDB.app.database().ref('/teams');
    this.teamsRef = ref;

    this.sdkDb = firebase.database().ref();
  }

cohort.service

export class CohortsService {
  private sdkDb;
  private core;
  private teamsRef;
  private cohortSubject: Subject<Cohort> = new Subject();

  constructor(
    private db: AngularFireDatabase,
    private feedsService: FeedsService,
    private http: Http,
    private coreDB: CoreDBService
  ) {
    coreDB.init(environment.fbCoreConfig);
    console.log(coreDB.app);
    this.core = coreDB.app;
    this.sdkDb = firebase.database().ref();
  }

coredb.service:

import {Injectable,Inject} from '@angular/core';
import * as firebase from 'firebase/app';
import { AngularFireDatabase, FirebaseListObservable, FirebaseObjectObservable } from 'angularfire2/database';


@Injectable()
export class CoreDBService {
  core:any;
  app;
  constructor (private db: AngularFireDatabase){}

  init(config){
    this.app = firebase.initializeApp(config, "core");
    const ref = this.app.database().ref('/teams');
    const listObs = this.db.object(ref);
    listObs.subscribe(data => console.log(data));
  }
}

@sudharsanmit
Copy link
Author

sudharsanmit commented Aug 26, 2017 via email

@sudharsanmit
Copy link
Author

sudharsanmit commented Aug 26, 2017 via email

@sudharsanmit
Copy link
Author

sudharsanmit commented Aug 26, 2017 via email

@daimz
Copy link

daimz commented Aug 26, 2017

No I want to use core in both the services, turns out what I did have wrong was having coreDB.init(environment.fbCoreConfig); in both cohorts.service and teams.service this effectively was telling firebase to initialize the core database twice.

I manage to resolve the error by moving coreDB.init(environment.fbCoreConfig); to my root.component (app.component for most setups) I could then still use the coreDb.service to access my database in the cohorts and teams services like this:
this.core = coreDB.app;

Now I can switch between the default database and my core database but including my coredb.service and I only initiate the database once.

Thanks for all the help!

@JumpLink
Copy link

How can I get his working if I want to define the app name on my imports?

@NgModule({
...
  imports: [
    AngularFireModule.initializeApp(environment.firebase, 'my-name'),
  ],

With my-name I get an error: No Firebase App '[DEFAULT]' has been created - call Firebase App.initializeApp() (app/no-app).

@47sharmamanu
Copy link

Where is"firebase" import used in:

firebase.initializeApp(config, "name");

@james11a
Copy link

james11a commented Jan 19, 2018

Hope this helps.

My solution is implemented in an Ionic application that I am working on.. As Google charges for having multiple databases in the same Firebase project, my setup has 2 Firebase projects instead of 2 databases in the same project. Below is my configuration:

Say the 2 Firebase application configuration variables are firebaseConfigA & firebaseConfigB with their names 'appA' & 'appB ' stored in firebaseAppNameA & firebaseAppNameB.

Note: It is recommended that all such configuration variables are stored in a separate configuration file / custom webpack environment files. The variables will be imported wherever required from here. In my case, I have custom webpack environment setup.
If you need help with setting up environments using custom webpack for Ionic, check out this fantastic post from @gshigeto: https://github.com/gshigeto/ionic-environment-variables

Anyway, to the code...

app.module.ts

import { firebaseConfigA, firebaseAppNameA } from "@app/env";
import { AngularFireModule } from "angularfire2";
import { AngularFireDatabaseModule, AngularFireDatabase } from "angularfire2/database";

@NgModule({
    declarations: [ ... ],
    imports: [
        ...
        AngularFireModule.initializeApp(firebaseConfigA, firebaseAppNameA),
        AngularFireDatabaseModule
    ],
    bootstrap: [IonicApp],
    entryComponents: [ ... ],
    providers: [
        ...
        AngularFireDatabase
    ]
})

All my Firebase related function are handled in a separate service:

firebase.service.ts

/** Angular imports */
import { Injectable } from "@angular/core";

/** 3rd-party imports */
import { AngularFireDatabase, AngularFireList, AngularFireObject } from "angularfire2/database";
import { _firebaseAppFactory } from "angularfire2/firebase.app.module";
import { FirebaseAppConfig } from "angularfire2";

@Injectable()
export class FirebaseService {
    private _db: AngularFireDatabase;

    constructor() { }

    /** Function to initialize firebase application and
     * get DB provider for the corresponding application.
     */
    public initFirebaseApp(config: FirebaseAppConfig, firebaseAppName: string) {
        this._db = new AngularFireDatabase(_firebaseAppFactory(config, firebaseAppName));
    }

    /** Function to get firebase DB list */
    public getList(path: string): AngularFireList<{}> {
        return this._db.list(path);
    }

    /** Function to get firebase DB object */
    public getObject(path: string): AngularFireObject<{}> {
        return this._db.object(path);
    }
}

Now, using the service in a component where I connect to both applications:

home.component.ts

// ... do all required imports
import {
    firebaseConfigA, firebaseAppNameA,
    firebaseConfigB, firebaseAppNameB
} from "@app/env";
import { FirebaseService } from "../../services/firebase.service";

@Component({
    selector       : "page-home",
    templateUrl    : "home.html"
})
export class ScannerDemoPage implements OnInit {
    constructor(private _firebaseService: FirebaseService) { }
    
    ngOnInit() {
        // Initialize 1st application
        this._firebaseService.initFirebaseApp(firebaseConfigA, firebaseAppNameA);
        let myList = this._firebaseService.getList("/path1");

        // Initialize 2nd application
        this._firebaseService.initFirebaseApp(firebaseConfigB, firebaseAppNameB);
        let myObj = this._firebaseService.getObject("/path2");
    }
}

You don't need to worry about re-initializing the Firebase application in multiple components as the _firebaseAppFactory() function takes care of that.

@texano00
Copy link

texano00 commented Jun 18, 2018

Hi @davideast

i've supposed that af is of type AngularFireDatabase but af.database.list doesn't exist.
Is your solution for the latest release?

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants