Google Cloud Functions: Return valid JSON

4,599

Solution 1

If you want to use the Flutter SDK to invoke a callable function, you need to actually define a callable function. Right now, you're declaring an HTTP function, which is not the same. Please read the documentation for callable functions to learn how to declare and implement a callable.

Instead of this:

functions.https.onRequest(...)

It will look like this:

functions.https.onCall(...)

Then, you return a JavaScript object to convert to JSON, rather than using a response object.

Solution 2

I could find the bug: As soon as you define another region that the default one, the flutter package cloud_functions seems not to be able to find the function anymore:

Works:

export const helloWorld = functions.https.onCall((data, context) => {
    return {
        message: "Hello World"
    }
});

Doesn´t work:

export const helloWorld = functions.region('europe-west1').https.onCall((data, context) => {
    return {
        message: "Hello World"
    }
});

Solution 3

I was having the same problem, and what worked for me was:

(Adding to @Michael 's answer)

When declaring and calling the cloud function, it's important to specify the region in both cases.

My mistake was that I was only setting the region code on the function declaration.

More here: https://firebase.google.com/docs/functions/locations#client-side_location_selection_for_callable_functions.

For Flutter you should specify the region in the region parameter of the singleton CloudFunctions:

CloudFunctions(app: FirebaseApp.instance, region: "europe-west1")
Share:
4,599
Michael
Author by

Michael

Updated on December 08, 2022

Comments

  • Michael
    Michael over 1 year

    I´m trying to call a Google Cloud Function from my Flutter App using the cloud_functions package.

    This is my Cloud Function:

    export const helloWorld = functions.region('europe-west1').https.onRequest((request, response) => {
    response.status(200).json({
        message: "Hello World!"
      });
    });
    

    And this is my flutter method that calls this function:

    try {
      final dynamic resp =
          await CloudFunctions.instance.call(
        functionName: "helloWorld"
      );
      print(resp);
    
    } on CloudFunctionsException catch (e) {
      ...
    } catch (e) {
      ...
    } finally {
      ...
    }
    

    As you can see it´s the most simply form of a request without any params.

    My problem: Each call to the Cloud Function results in a CloudFunctionsException. Reason: "Response is not valid JSON object.".

    Maybe somebody has an idea what´s going wrong here? If I call the cloud function via Postman or a browser, a valid JSON Object is returned and no exception is thrown.

    Thanks in advance, Michael

  • Michael
    Michael over 5 years
    That´s exactly what I did first according to the module documentation - with the same exception thrown: export const helloWorld = functions.https.onCall((data, context) => { return { message: "Hello World" } });
  • Doug Stevenson
    Doug Stevenson over 5 years
    If you change the region of the function in its definition, you are also changing its url. The funcitons client SDK doesn't know that you've done this, so you need to tell it the region so it can build the URL correctly. In android, you change the region with getInstance(region). Don't know how it works on Flutter, probably similar.
  • Michael
    Michael over 5 years
    Seems that this is not supported by the package at the moment - I will suggest it on GitHub. Thanks for your inputs!
  • Théo Champion
    Théo Champion over 4 years
    having the same problem here, did you get any updates on this @Michael ?
  • Marco Nascimento
    Marco Nascimento about 4 years
    Thank you @Michael ! Saved my evening!
  • user425678
    user425678 about 4 years