Flutter Firebase Cloud function can not be called

Viewed 5373

I am getting an error whilst using Firebase Cloud Functions when I try to call a callable function from Flutter.

flutter: caught generic exception
flutter: PlatformException(functionsError, Firebase function failed with exception., {message: NOT FOUND, code: NOT_FOUND})

Here is how I try to call the cloud function with using cloud_functions: ^0.4.2+3

import 'package:cloud_functions/cloud_functions.dart';
      _check(String id) async {
        HttpsCallable callable = CloudFunctions.instance
            .getHttpsCallable(functionName: 'checkUserFavorites');
        try {
          final HttpsCallableResult result = await callable.call(
            <String, dynamic>{
              'id': id,
            },
          );
          print(result.data);
        } on CloudFunctionsException catch (e) {
          print('caught firebase functions exception');
          print(e.code);
          print(e.message);
          print(e.details);
        } catch (e) {
          print('caught generic exception');
          print(e);
        }
      }
4 Answers

I have experienced similar issues, and with few days of debugging and experimenting I found the solution only after studying the source code of Cloud Functions Plugin for Flutter.

When you deploy Firebase Cloud function, you can choose any region of preference (closer to your application the better). For example

// using DigitalOcean spaces
exports.generateCloudImageUrl = functions
    .region('europe-west3')
    .https.onCall((reqData, context) => {
...
}

When you want to call this function from Flutter app, you must specify the region, otherwise all goes to us-central1 which is default. See example code on how to use a function deployed in a specific region

final HttpsCallable generateCloudImageUrl = new CloudFunctions(region: "europe-west3")
      .getHttpsCallable(functionName: 'generateCloudImageUrl');

// NB! if you initialize with 'CloudFunctions.instance' then this uses 'us-central1' as default region! 

see cloud_function source for init.

Update, as of recent release, you can initialize as below;

FirebaseFunctions.instanceFor(region: "europe-west3").httpsCallable(
            "generateCloudImageUrl",
            options:
                HttpsCallableOptions(timeout: const Duration(seconds: 30)));

Cloud functions are supported in the regions that you are currently running them, according to the Cloud Functions Location Documentation, but not in all regions.

According to what you shared in the comments, I would say that there are 3 cenarios to your issue:

  • europe-west1: The function is probably out of date, since you are getting an unespected data format error, which suggest that it expects different data/format than your default function.

  • europe-west2: The function is not deployed in this region, this is hinted in the error message message: NOT FOUND.

  • Default Function (unknown region): This is the most recent version of the function, on a region different than europe-west1 and europe-west2, and it accepts the call with the data in the format that you are sending.

NOTE: You can check which regions you currently have your cloud function deployed on the cloud functions dashboard, as you can see on the example image below:

enter image description here

Also, I suspect that the default region you using is us-central1, since according to the documentation:

By default, functions run in the us-central1 region

To fix your issue, I suggest that you redeploy your current version of the function to the europe-west regions that you intend to use.

There are three reasons this error mostly happens:

1. Call the correct function:

Make sure to call the correct function in its full name (visible when you start a local emulator). Espacially if you have additional exports of files in your index.js file make sure to call the export name as well.

Syntax: serverLocation-optionalExportParent-yourFunction

Example: us-central1-post_functions-updateShare

Note that the server location can also be configured in your instance

2. Emulator: Same WIFI

Make sure to be connected to the same wifi, when using the emulator. Otherwise, any call will end in unvailablity resulting in

Unhandled Exception: [firebase_functions/unavailable] UNAVAILABLE

3. Emulator: Correct host configuration

To connect to a physical device the host at all emulators at your firebase.json must be configured: Simply add "host": "0.0.0.0".

Now the host in flutter needs to be your ip-adress of the computer. More on that here

In my case, in addition to the regional issue, what really solved to me was to include the script below in index.html:

<script src="https://www.gstatic.com/firebasejs/8.10.1/firebase-functions.js"></script>
Related