Flutter Firebase云函数无法调用。

8

当我尝试从Flutter调用可调用函数时,我在使用Firebase Cloud Functions时遇到了错误。

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

以下是我尝试使用 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);
        }
      }

1
问题似乎与云函数本身有关。当它们在region('europe-west1')或region('europe-west2')中运行时,会出现PlatformException(3840, The data couldn’t be read because it isn’t in the correct format., null)或PlatformException(functionsError, Firebase function failed with exception., {message: NOT FOUND, code: NOT_FOUND})的错误。可调用函数是否不支持所有区域?当未定义区域时,函数按预期运行,没有任何问题或错误。 - Ben
4个回答

15

我曾经遇到过类似的问题,在经过几天的调试和实验后,我只有在研究Flutter云函数插件的源代码后才找到了解决方案。

当你部署Firebase云函数时,可以选择任何偏好的区域(越靠近应用程序越好)。例如:

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

当您想从Flutter应用程序调用此函数时,必须指定区域,否则所有内容都将默认发送到us-central1。请参阅示例代码以了解如何使用在特定区域部署的函数。

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! 

查看云函数源代码以进行初始化。

截至最新发布版本, 您可以按以下方式进行初始化;

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

直到我添加了 <script src=". . ./firebasejs/7.16.0/firebase-functions.js"></script> 到 /web/index.html,尽管我做了所有的事情,问题仍未得到解决。 - SarkawtNoori
1
截至2021年3月: 文档 您可以这样初始化: final FirebaseFunctions _firebaseFunctions = FirebaseFunctions.instanceFor(region: 'europe-west3'); - goldensoju
谢谢@金色烧酒,我刚刚根据你的评论更新了答案。 - Yilmaz Guleryuz

1

根据Cloud Functions Location Documentation,云函数仅在您当前运行它们的地区受支持,而不是所有地区。

根据您在评论中分享的内容,我认为您遇到的问题有三种情况:

  • europe-west1:函数可能已经过时,因为您收到了一个意外的数据格式错误,这表明它期望的数据/格式与您的默认函数不同。

  • europe-west2:该函数未在此地区部署,这在错误消息message: NOT FOUND中暗示。

  • 默认函数(未知地区):这是函数的最新版本,位于不同于europe-west1europe-west2的地区,并且接受以您发送的格式的数据调用。

注意:您可以在云函数仪表板上查看您当前部署云函数的地区,如下面示例图所示:

enter image description here

此外,我怀疑您使用的默认区域是us-central1,因为根据文档:
默认情况下,函数在us-central1区域运行。
为了解决您的问题,我建议您将当前版本的函数重新部署到您打算使用的欧洲西部区域。

如果我不配置默认值,它将使用us-central1。我的数据库位于europe-west3。我所有其他的函数都部署在europe-west1,并且它们按预期工作。然而,在europe-west1部署可调用函数却无法正常工作。现在我已经使用了默认值us-central1并且它可以正常工作。让我想知道是否支持在europe-west1中使用可调用函数。 - Ben
正如我在答案中所评论的,europe-west1 是支持云函数的区域之一,所有这些区域都支持所有类型的函数,包括可调用函数,因此我不认为它是区域本身的问题。你在部署时是否遇到任何错误或日志,以便我们进行故障排除? - Ralemos
1
实际上,这不是区域问题,我只是找到了一个简单的解决方案,并将在下面的答案中附上代码示例。 - Yilmaz Guleryuz
@guleryuz 我有同样的问题,除了默认值us-central1之外的任何值,云函数都不会被调用,也没有日志。您能像您说的那样发布答案吗? - Loolooii
答案及解决方案已发布,请查看问题下方的已接受答案。如果对您有用,请记得投赞成票 ;) - Yilmaz Guleryuz
显示剩余7条评论

0
在我的情况下,除了区域问题之外,真正解决我的方法是在index.html中包含以下脚本:
<script src="https://www.gstatic.com/firebasejs/8.10.1/firebase-functions.js"></script>

0

这个错误通常有三个原因:

1. 调用正确的函数:

确保以完整名称(在启动本地模拟器时可见)调用正确的函数。特别是如果您在index.js文件中有其他文件的导出,请确保也调用导出名称。

语法:serverLocation-optionalExportParent-yourFunction

示例:us-central1-post_functions-updateShare

请注意,服务器位置也可以在您的实例中进行配置

2. 模拟器:相同的WIFI

使用模拟器时,请确保连接到相同的wifi。否则,任何调用都将以不可用结束。

Unhandled Exception: [firebase_functions/unavailable] UNAVAILABLE

3. 模拟器: 正确的主机配置

为了连接到物理设备,必须在firebase.json上的所有模拟器中配置主机: 只需添加"host": "0.0.0.0"

现在Flutter中的主机需要是你计算机的IP地址。更多信息请点击此处


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接