簡體   English   中英

`httpsCallable` 與 `httpsCallableFromURL` 可調用 Firebase 函數

[英]`httpsCallable` vs. `httpsCallableFromURL` callable Firebase Functions

httpsCallableFromURL工作正常,但httpsCallable返回null 怎么了?

模擬器日志顯示 Cloud Functions 從httpsCallableFromURLhttpsCallable正確執行。 我的瀏覽器控制台使用httpsCallableFromURL記錄UPPERCASE (如果我輸入uppercase )。 但是使用httpsCallable時,瀏覽器控制台會記錄null

似乎null日志幾乎立即出現,但UPPERCASE需要一些時間才能記錄。 我的猜測是返回在函數之前執行?

還有一個問題。 我在功能列表的 Firebase 控制台中找到了已部署功能的 URL。 模擬器中有什么地方可以找到在模擬器中調用函數的 URL 嗎? 此 URL 由 Github Copilot 編寫:此 URL 也有效: http://localhost:5001/my-projectId/us-central1/upperCaseMe

索引.ts

import * as functions from "firebase-functions";

export const upperCaseMe = functions.https.onCall((data, context) => {
    const original = data.text;
    const uppercase = original.toUpperCase();
    functions.logger.log('upperCaseMe', original, uppercase);
    return uppercase;
});

應用程序組件.ts

import { Component } from '@angular/core';
import { getFunctions, httpsCallable, httpsCallableFromURL } from "firebase/functions";
import { initializeApp } from 'firebase/app';
import { environment } from '../environments/environment';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent {
  firebaseConfig = environment.firebaseConfig;
  firebaseApp = initializeApp(this.firebaseConfig);

  messageText: any;
  functions = getFunctions(this.firebaseApp);

  callMe(messageText: any) {
    console.log("Calling Cloud Function: " + messageText);
    // const upperCaseMe = httpsCallable(this.functions, 'upperCaseMe');
    const upperCaseMe = httpsCallableFromURL(this.functions, 'http://127.0.0.1:5001/my-projectId/us-central1/upperCaseMe');
    upperCaseMe({ text: messageText })
      .then((result) => {
        console.log(result.data)
      })
      .catch((error) => {
        console.error(error);
      });;
  };
}

我能夠讓httpsCallableFromURL返回null

import * as functions from "firebase-functions";

export const upperCaseMe = functions.https.onCall((data, context) => {
    const original = data.text;
    const uppercase = original.toUpperCase();
    setTimeout(() => {
        console.log("Wait ten seconds.");
        functions.logger.log('upperCaseMe', original, uppercase);
        return uppercase;
      }, 10000)
});

這從不在模擬器中記錄任何內容,並且始終在瀏覽器控制台中記錄null 它在一兩秒后記錄null ,而不是十秒。 httpsCallableFromURLhttpsCallable的結果相同。

httpsCallable使用由 Cloud Functions 托管的已部署代碼。 該 URL 源自您在 Firebase SDK 初始化期間傳遞的數據。 它不使用模擬器,除非您將 SDK 配置為這樣做。 我建議查看有關此事的文檔

要檢測您的應用以與模擬器交互,您可能需要進行一些額外的配置。

如果您的原型和測試活動涉及可調用的后端函數,請像這樣配置與 Cloud Functions for Firebase 模擬器的交互:

 import { getApp } from "firebase/app"; import { getFunctions, connectFunctionsEmulator } from "firebase/functions"; const functions = getFunctions(getApp()); connectFunctionsEmulator(functions, "localhost", 5001);

httpsCallableFromURL適用於您無法使用 SDK 定位后端的正常方式的情況,例如,如果您在不是正常 Cloud Functions 后端的某些服務上托管可調用函數,或者您正嘗試調用一個函數不屬於您的應用程序的項目。

我絕不會期望 Copilot 在任何情況下都能生成正確的代碼。 最好依靠文檔來告訴您該怎么做。

我錯誤地初始化了 Firebase。 Firebase 應該在app.module.ts中初始化,而不是在app.component.ts中。 然后應該將 Firebase 注入到app.component.ts中。 當我正確初始化 Firebase 時, httpsCallablehttpsCallableFromURL都將大寫消息返回到瀏覽器控制台。

應用程序模塊.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';

// Angular
import { environment } from '../environments/environment';
import { FormsModule } from '@angular/forms';

// AngularFire
import { provideFirebaseApp, initializeApp } from '@angular/fire/app';
import { provideFunctions,getFunctions, connectFunctionsEmulator } from '@angular/fire/functions';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    provideFirebaseApp(() => initializeApp(environment.firebase)),
    provideFunctions(() => {
      const functions = getFunctions();
      if (!environment.production) {
        connectFunctionsEmulator(functions, 'localhost', 5001);
      }
      return functions;
    }),
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

我更改了視圖以僅通過ngModel傳遞消息。 通過callMe(messageText)傳遞消息是多余的。

應用程序組件.html

<h3>Call cloud function</h3>
<form (ngSubmit)="callMe()">
    <input type="text" [(ngModel)]="messageText" name="message" placeholder="message" required>
    <button type="submit" value="Submit">Submit</button>
</form>

我將組件控制器更改為注入Functions ,而不是在組件控制器中初始化 Firebase:

應用程序組件.ts

import { Component, Inject } from '@angular/core';
import { Functions, httpsCallable, httpsCallableFromURL } from '@angular/fire/functions';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent {
  constructor(
    @Inject(Functions) private readonly functions: Functions,
  ) {}

  messageText: string = '';

  callMe() {
    console.log("Calling Cloud Function: " + this.messageText);
    const upperCaseMe = httpsCallable(this.functions, 'upperCaseMe');
    // const upperCaseMe = httpsCallableFromURL(this.functions, 'http://127.0.0.1:5001/languagetwo-cd94d/us-central1/upperCaseMe');
    upperCaseMe({ text: this.messageText })
      .then((result) => {
        console.log(result.data)
      })
      .catch((error) => {
        console.error(error);
      });;
  };
}

index.ts沒有變化。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM