【问题标题】:How to call Google Places API from within Firebase Cloud Functions?如何从 Firebase Cloud Functions 中调用 Google Places API?
【发布时间】:2021-06-30 13:14:37
【问题描述】:

我正在尝试借助 Google Places API 及其自动完成功能在我的 Flutter 应用中实现位置自动完成功能。为了使 API 调用逻辑和 API 密钥远离客户端,Flutter App 应该调用 Firebase Cloud Function,然后调用 Google Places API。我一直试图让这个工作好几天,通过各种文章工作,我就是无法取得任何进展。这是我的 Firebase Cloud Function 的源代码:

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

export const autofillSuggestions = functions.region("europe-west3")
    .https.onCall(async (data) => {
      const input = data.input;
      const sessionToken = data.sessiontoken;

      // will be stored as an environment variable, as soon as i get cloud function to work
      const googleAPIKey = "my_api_key"; 
      

      const requestURL = "https://maps.googleapis.com/maps/api/place/autocomplete/json?input=" + input +
     "&key=" + googleAPIKey + "&sessiontoken=" + sessionToken;

      return await axios.default.get(requestURL).then((apiResponse) => {
        return {predictions: apiResponse.data.predictions,
        };
      })
          .catch((error) => {
            console.log(error);
          });
    });

这个源代码被导入到index.ts,然后再次导出文件,所以问题不应该存在。 Flutter App 内部的云函数调用逻辑如下所示:

HttpsCallable _getCallable(String functionName) =>
      FirebaseFunctions.instance.httpsCallable(functionName);

 Future<dynamic> _getSuggestionsFromGoogleMapsAPI(String input) async {
    //FirebaseFunctions.instance
    //    .useFunctionsEmulator(origin: 'http://localhost:5001');
    final callable = _getCallable('autofillSuggestions');

    try {

      final data = HashMap.of({
        'sugg': input,
        'sessionToken': _sessionToken,
      });
      final response = await callable.call(data);
      return response.data;
    } catch (e) {
      print(e);
      throw AutocompletionFailure();
    }
  }

当我在 Flutter 应用程序中触发 Cloud Function Call 并取消注释提到 useFunctionsEmulator 的行时,一切正常。但是一旦我再次注释掉这些并想与真正的 Firebase 服务器通信,我总是在 VS Code 调试控制台中收到此错误消息:

[firebase_functions/internal] Response is not valid JSON object.

Firebase 服务器上的错误日志如下所示:

autofillSuggestions
{
 "@type":"type.googleapis.com/google.cloud.audit.AuditLog",
 "authenticationInfo":{"principalEmail":"my@mail.com"},
 "requestMetadata": 
   {
     "callerIp":"10.10.101.101",
     "callerSuppliedUserAgent":"FirebaseCLI/9.8.0,gzip(gfe),gzip(gfe)",
     "requestAttributes":{"time":"2021-04-04T09:34:15.120516Z","auth":{}},
     "destinationAttributes":{}
   },
 "serviceName":"cloudfunctions.googleapis.com",
 "methodName":"google.cloud.functions.v1.CloudFunctionsService.SetIamPolicy",
 "authorizationInfo":
   [
    {
     "resource":"projects/my-project/locations/europe-west3/functions/autofillSuggestions",
     "permission":"cloudfunctions.functions.setIamPolicy",
     "granted":true,
     "resourceAttributes":{}
    },
    {
     "permission":"cloudfunctions.functions.setIamPolicy",
     "granted":true,
     "resourceAttributes":{}
    }
   ],
 "resourceName":"projects/my-project/locations/europe-west3/functions/autofillSuggestions",
 "request":
   {
    "updateMask":"version,bindings",
    "resource":"projects/my-project/locations/europe-west3/functions/autofillSuggestions",
    "policy":
      {
       "bindings":
         [
          {
           "members":["allUsers"],
           "role":"roles/cloudfunctions.invoker"
          }
         ]
      },
    "@type":"type.googleapis.com/google.iam.v1.SetIamPolicyRequest"
   },
 "response":
   {
    "bindings":
        [
         {
          "members":["allUsers"],
          "role":"roles/cloudfunctions.invoker"
         }
        ],
    "@type":"type.googleapis.com/google.iam.v1.Policy","etag":"BwW/IkjRmog="
   },
 "resourceLocation":{"currentLocations":["europe-west3"]}
}

由于它没有提及Function execution startedFunction execution terminated with ... 之类的内容,我怀疑根本没有调用云函数...我的想法是否正确?如果是的话,有谁知道如何让它工作???

我非常关注thisthis article。我还发现this 很有趣,但还没有尝试过,因为我认为我的主要问题是云函数甚至没有被调用......

【问题讨论】:

    标签: typescript flutter autocomplete google-cloud-functions google-places-api


    【解决方案1】:

    答案是 - 当然 - 非常愚蠢,但我想这是 IT 和自学成才的诅咒...... 如您所见,由于我的位置,我将europe-west3 指定为我的云函数的区域。但是在获取callable引用时,我没有指定区域,导致cloud_functionsflutter包创建了一个FirebaseFunctions实例,默认区域设置为us-central1。这弄乱了通话并导致了内部错误。简单的解决方法是在颤振应用程序中:

    _getCallable 的新实现:

    HttpsCallable _getCallable(String functionName) {
       return FirebaseFunctions.instanceFor(region: 'europe-west3')
           .httpsCallable(functionName);
    }
    

    【讨论】:

      猜你喜欢
      • 2020-03-15
      • 2020-05-23
      • 2018-01-24
      • 1970-01-01
      • 2019-12-30
      • 2021-02-04
      • 2018-07-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多