8

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);
        }
      }
Ben
  • 650
  • 2
  • 12
  • 23
  • 1
    The issue seems to be related to the cloud function itself. When they run in region('europe-west1') or region('europe-west2') they fail with PlatformException(3840, The data couldn’t be read because it isn’t in the correct format., null) or PlatformException(functionsError, Firebase function failed with exception., {message: NOT FOUND, code: NOT_FOUND}). Are Callable functions not supported across all regions? When not defining a region the function run as expected without any issues or errors. – Ben Apr 06 '20 at 09:17

4 Answers4

14

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)));
Yilmaz Guleryuz
  • 9,313
  • 3
  • 32
  • 43
  • doing all that still didn't fix the issue for me untill i added to /web/index.html – SarkawtNoori Jul 19 '20 at 00:21
  • 1
    as of March 2021: [Docs](https://firebase.flutter.dev/docs/functions/usage/#specifying-regions) So you could initialize as `final FirebaseFunctions _firebaseFunctions = FirebaseFunctions.instanceFor(region: 'europe-west3');` – goldensoju Mar 10 '21 at 06:14
  • thnx @goldensoju , just updated the answer by your comment. – Yilmaz Guleryuz Mar 13 '21 at 21:00
1

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.

Ralemos
  • 5,571
  • 2
  • 9
  • 18
  • If I don't configure a default it will is us-central1 indeed. My DB is located at europe-west3. All my other functions are deployed to europe-west1 and they work as expected. However deploying a callable function in europe-west1 does not work. I have now used the default us-central1 and it works. Let me wonder if callable functions are supported in europe-west1. – Ben Apr 06 '20 at 17:40
  • As I commented in the answer, `europe-west1` is listed as a region that supports cloud functions, all those regions support all types of functions, including callable functions, so I wouldn't say it's an issue with the region itself. Do you get any errors or logs on that deploy so we can troubleshoot? – Ralemos Apr 07 '20 at 12:18
  • When deployed to europe-west1 I can't even see LOGS when the function is called. – Ben Apr 08 '20 at 13:37
  • try completetly deleting your instance of the function in that region and re-deploy it. – Ralemos Apr 08 '20 at 14:12
  • Happy to try again but already done this multiple times. Will keep you posted! – Ben Apr 08 '20 at 16:24
  • Nothing is happening when deploy to europe-west1 when the function is called. Even the LOGS don't show anything. – Ben Apr 18 '20 at 11:13
  • i'm having similar issue. tried delete-redeploy few times, even logs are not showing. issue began after changing the region from default us to europe-west3 – Yilmaz Guleryuz Apr 19 '20 at 19:59
  • strangely, when I switch back to default region `us-central1`, it works fine.... – Yilmaz Guleryuz Apr 19 '20 at 20:03
  • @guleryuz Since you and Ben are both experiencing the same issue on the same region, I would say that this is probably an issue in this specific region in GCP. I would suggest that you open a ticket on Google's [public issue tracker](https://issuetracker.google.com/) system so that they can work on fixing it, as they might not even be aware of it. I will also add this to the answer above, so that the community can be aware of this without coming to the comments. – Ralemos Apr 20 '20 at 09:48
  • 1
    actually, it is not region issue, I just found the reason with a simple solution, I'll append with code example in the answer below. – Yilmaz Guleryuz Apr 20 '20 at 17:04
  • @guleryuz I have the exact problem, anything other than `us-central1` (the default), the cloud function does not get called and there are no logs. Would you post the answer as you said? – Loolooii Apr 23 '20 at 21:22
  • the answer with solution is already posted, see accepted answer right under the question. if it works for you, then plz remember to vote up ;) – Yilmaz Guleryuz Apr 24 '20 at 10:10
0

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

Paul
  • 1,349
  • 1
  • 14
  • 26
0

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>