0

I have two firebase functions deployed, one uses functions.https.onRequest (companyRequest) and one uses functions.https.onCall (companyCall). Both do the exact same thing: retrieve a document from firestore (the exact same document from the exact same collection).

Here are the functions:

import * as functions from "firebase-functions";
import * as admin from "firebase-admin";

admin.initializeApp(functions.config().firebase);

export const companyRequest = functions.https.onRequest((request, response) => {
  const companyId = "VpOVFo82m9ls3aIK7dra";
  admin
    .firestore()
    .collection("company")
    .doc(companyId)
    .get()
    .then(result => {
      response.send(result.data());
    })
    .catch(error => {
      response.send(error);
    });
});

export const companyCall = functions.https.onCall((data, context) => {
  if (context && context.auth) {
    console.log(
      "AUTH",      
      context.auth.uid,
      context.auth.token.email
    );
  }
  const companyId = "VpOVFo82m9ls3aIK7dra";
  admin
    .firestore()
    .collection("company")
    .doc(companyId)
    .get()
    .then(result => {
      return result.data();
    })
    .catch(error => {
      return error;
    });
});

I call companyRequest with curl and it works:

> curl https://us-central1-xxxxx.cloudfunctions.net/company
{"name":"Duny Comp."}

I call companyCall from flutter and it fails (on firebase, server site):

Future click() async {
  final HttpsCallable callable = CloudFunctions.instance.getHttpsCallable(
    functionName: 'companyCall',
  );
  HttpsCallableResult resp = await callable.call(<String, dynamic>{
    'companyId': 'VpOVFo82m9ls3aIK7dra',
  });
  print(resp.data);
}

the error I get for companyCall is this:

AUTH 3gvfgYJpk2gIgUpkOLxdkdId uuuu@xxxx.com
ERROR:  Error: Could not load the default credentials. Browse to https://cloud.google.com/docs/authentication/getting-started for more information

The error seems quite clear, but why does the unauthenticated call with curl work, but companyCall with firebase authentication via flutter does have a permission problems? In the output you can even see the auth information from the enduser in the flutter app, so he is authenticated.

The question is, why there is a difference between the two? The proposed solutions like Error: Could not load the default credentials (Firebase function to firestore) also feel very strange...

Update:

This is not the same question as in Firebase Cloud Functions: Difference between onRequest and onCall, in this question I ask why there is a difference in the security behaves different between the two different methods. Why do I need to authenticate with an admin account to access the same collection from onCall as I don't need it when access the collection from a onRequest method?

domi
  • 2,167
  • 1
  • 28
  • 45
  • Is it maybe a typo or I misunderstood this? When you say you call `companyRequest` with `curl`, according to the snippet that follows you are calling `companyCall`, and that works out fine. In any case, [here](https://stackoverflow.com/questions/51066434/firebase-cloud-functions-difference-between-onrequest-and-oncall?noredirect=1&lq=1) there is an interesting reading to know some differences between those 2 – Pablo Almécija Rodríguez Oct 17 '19 at 12:20
  • sorry, yes it was a typo - the answer you refer to is the same as I posted in my question above... – domi Oct 17 '19 at 12:46
  • 1
    The link I sent is to add information on your question about the differences between **onCall** and **onRequest**. I fail too see anything related to that in the link you added in your question. – Pablo Almécija Rodríguez Oct 22 '19 at 07:29
  • my bad - sorry!! – domi Oct 22 '19 at 15:51
  • Possible duplicate of [Firebase Cloud Functions: Difference between onRequest and onCall](https://stackoverflow.com/questions/51066434/firebase-cloud-functions-difference-between-onrequest-and-oncall) – Pablo Almécija Rodríguez Oct 28 '19 at 15:56

0 Answers0