Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use collectionGroup in @angular/fire 7+

I would do a search form using keywords, I can do it with more ancient versions of @angular/fire but not with this one.

Always the same error :

FirebaseError : missing or insufficient permissions

I've tried to implement a collectionGroup new function inside my Angular app but it shows the error above.

Then I've tried to create a firebase function to return my collectionGroup but I can't re-use the object because it's not @angular/fire, it's purely firebase, right ?

Inside my component :

import {
  collectionData,
  collectionGroup,
  DocumentData,
  Firestore,
  query,
  where,
} from '@angular/fire/firestore';

search() {
if (this.searchForm.value.search.length) {
  let substances = collectionGroup(this.afStore, 'substance');
  // ERROR FirebaseError: Missing or insufficient permissions.
  let query$ = query(
    substances,
    where('keywordsName', 'array-contains', this.searchForm.value.search)
  );
  let res = collectionData(query$);
  let res$ = res.pipe(
    map((families: DocumentData[]) => {
      families.forEach((family: DocumentData) => {
        family['color'] = this.riskReduction.generateRandomColor();
      });
      return families;
    })
  );
  this.riskReduction.setSubstances(res$);
} else {
  this.riskReduction.setSubstances(this.riskReduction.getSubstances());
}
}

Edit : Else I tried with the function :

/**
 * ANCHOR: Search a substance
 */

export const searchSubstance = functions.https.onCall(async (data, context) => {
  try {
    const ref = admin.firestore().collectionGroup('substance');
    return <BasicResponse>{
      status: 'success',
      data: { substances: ref.get() },
    };
  } catch (e) {
    console.log(e);
    return <BasicResponse>{ status: 'error', message: e };
  }
});

thanks for your help

like image 918
F3LENYR Avatar asked Jan 26 '26 12:01

F3LENYR


1 Answers

The error:

PERMISSION_DENIED: Missing or insufficient permissions

Means that this exception is thrown because the Firebase servers rejected the operation, this can be fixed by changing the Cloud Firestore Security Rules You can try the following rules (only for testing):

rules_version = '2';
service cloud.firestore {
 match /databases/{database}/documents {
   match /{document=**} {
     allow read, write: if true;
   }
 }
}

The rules are only recommended for testing purposes since anyone that has your project ID can read or write. You can implement several security measures, here is an excellent article by Alex Mamo (a member of the community) that you can use to implement several other more secure security rules.

1st UPDATE

Since we are retrieving results from a collection group consisting of collections, you need to use recursive wildcard {name=**}

When using the recursive wildcard syntax, the wildcard variable will contain the entire matching path segment, even if the document is located in a deeply nested subcollection. For example, the rules listed above would match a document located at /cities/SF/landmarks/coit_tower, and the value of the document variable would be SF/landmarks/coit_tower.

In version 2 of the security rules, recursive wildcards match zero or more path items. match/cities/{city}/{document=**} matches documents in any sub-collections and documents in the cities collection.

You must opt-in to version 2 by adding rules_version = '2'; at the top of your security rules:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the cities collection as well as any document
    // in a subcollection.
    match /cities/{city}/{document=**} {
      allow read, write: if <condition>;
    }
  }
}

You can have at most one recursive wildcard per match statement, but in version 2, you can place this wildcard anywhere in the match statement. For example:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the songs collection group
    match /{path=**}/songs/{song} {
      allow read, write: if <condition>;
    }
  }
}

We can avoid this error altogether by implementing Firebase Admin SDK, this will bypass the security rules entirely.

I also find this github theard that explains how to avoid getting this error doing the following:

  1. Go to IAM and admin
  2. Select the Service accounts menu on the left hand side
  3. Under 'Service accounts for project '[Project Name]' copy the Email of the account that has 'App Engine default service account' under its Name column (should be [project_id]@appspot.gserviceaccount.com).
  4. Select the IAM menu from the left hand side
  5. Click +ADD on the very top (next to the 'IAM' title)
  6. In the field 'New principals' paste the service account email copied in point 3
  7. Select the role 'Firebase Admin SDK Administrator Service Agent'
  8. Click SAVE.
like image 113
Andres Fiesco Casasola Avatar answered Jan 28 '26 03:01

Andres Fiesco Casasola



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!