Yafaa ats
Yafaa ats

Reputation: 31

Multiple Firebase Project in same Angular app

I followed this tutorial to configure my angular app to use two Firebase Projects, the main code is as following
in app.module

export function AngularFirestoreProject1(platformId: Object, zone: NgZone) {
  return new AngularFirestore(environment.project1, 'project1', false, null, platformId, zone, null, null, null);
}

export function AngularFireAuthProject1(platformId: Object, zone: NgZone) {
  return new AngularFireAuth(environment.project1, 'project1-auth', platformId, zone,null, null, null, null, null, null);
}

export function AngularFirestoreProject2(platformId: Object, zone: NgZone) {
  return new AngularFirestore(environment.project2, 'project2', false, null, platformId, zone, null, null, null);
}

export function AngularFireAuthProject2(platformId: Object, zone: NgZone) {
  return new AngularFireAuth(environment.project2, 'project2-auth', platformId, zone,null, null, null, null, null, null);
}

in the providers section

  providers: [
   {
    provide: 'env',
    useValue: environment
   },
   {
    provide: 'firebaseProject1',
    deps: [PLATFORM_ID, NgZone],
    useFactory: AngularFirestoreProject1
   },
   {
    provide: 'firebaseProject2',
    deps: [PLATFORM_ID, NgZone],
    useFactory: AngularFirestoreProject2
   },
   {
    provide: 'firebaseAuthProject1',
    deps: [PLATFORM_ID, NgZone],
    useFactory: AngularFireAuthProject1

   },
   {
    provide: 'firebaseAuthProject2',
    deps: [PLATFORM_ID, NgZone],
    useFactory: AngularFireAuthProject2
   }
  ],

The problems that i can see :

1- the syntaxes of angularFirestore and AngularFireAuth requires more parameters, i ended up by adding null parameters

2- the solution works but when i add the security rules that i used to have when the app was working with 1 firebase project and i want to perform an action as an admin, i get this error

core.js:4352 ERROR Error: Uncaught (in promise): FirebaseError: [code=permission-denied]: Missing or insufficient permissions.
FirebaseError: Missing or insufficient permissions.
    at new n (index.cjs.js:129:1)
    at index.cjs.js:13082:1
    at Y.<anonymous> (index.cjs.js:13037:1)
    at ub (index.esm.js:358:1)
    at push.x7I3.g.dispatchEvent (index.esm.js:338:45)
    at push.x7I3.Z.sa (index.esm.js:1340:32)
    at qc (index.esm.js:691:1)
    at tc (index.esm.js:584:1)
    at push.x7I3.g.Ca (index.esm.js:557:1)
    at push.x7I3.g.Wa (index.esm.js:519:52)
    at resolvePromise (zone-evergreen.js:798:1)
    at dr.reject (zone-evergreen.js:705:1)
    at xs (index.cjs.js:11827:1)
    at index.cjs.js:11784:1
    at step (tslib.es6.js:100:1)
    at Object.next (tslib.es6.js:81:45)
    at fulfilled (tslib.es6.js:71:42)
    at ZoneDelegate.invoke (zone-evergreen.js:364:1)
    at Object.onInvoke (core.js:27486:1)
    at ZoneDelegate.invoke (zone-evergreen.js:363:1)

the rules are simple as :

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{collection}/{document}/{path=**} {
      allow read: if canRead(collection, document);
      allow write: if canWrite(collection, document);
    }
    function canRead(collection, document) {
      return isAdmin() || isAccessible(collection, document) ;
    }
    function canWrite(collection, document) {
      return isAdmin();
    }
    function isAccessible(collection, document) {
      return collection != 'users' || isOwner(document);
    }
    function isSignedIn() {
      return request.auth != null;
    }
    function hasRole(role) {
      return isSignedIn() && get(/databases/(database)/documents/users/$(request.auth.uid)).data.role == role;
    }
    function isAdmin() {
      return hasRole('admin');
    }
    function isOwner(ownerId) {
      return isSignedIn() && request.auth.uid == ownerId;
    }
  }
}

It seems like in my rules the request.auth is null, i don't know what's wrong or is there any better solution

Upvotes: 1

Views: 452

Answers (1)

Vaidehi Jamankar
Vaidehi Jamankar

Reputation: 1346

The error message you get means that your application is trying to read or write some data that you don't have access to,as authorization does not work between project boundaries.You will need to authenticate the user into the project whose data you want to access.

One solution is to configure the two projects in your app, as described in the Configure multiple projects doc.A common approach is to have your main app in a first Firebase Project, using the Auth service of this project. And then use a second Firebase project just for the hosting of the Admin dashboard app. But, in the Admin dashboard app, you point to the first project.

As in your code above it is seen you are using different four function calls and also in providers section instead of going for multiple authorization rules.You can use the ID authentication for one as default and then add up other to share with and configure rules.Once you have set up authentication for a default project ,use the underlying ClientID just as an identifier and add the same to a whitelist specified requestIdToken call.

With this ,you can navigate to the Auth section of the secondary project and add it up there.

Also check these similar examples for more details:

I would also recommend to check out these thread for Multiple Firebase projects in one angular app, Dependency injection in action, Multiple project example

Upvotes: 1

Related Questions