我的代码可以编译,但是当我调用函数时,我得到了一个CORS错误。阅读this answer时,似乎Angular正在向Firebase云函数发送一个获取请求,但是Firebase云函数拒绝了该请求,并且有某种方法可以告诉Firebase云函数接受来自Angular的请求(http://localhost:4200/)?
我看到了storage.rules
,但没有看到functions.rules
文件。在我的Firebase控制台中,我看到了Firestore和存储的规则,但没有看到函数的规则。
我将hosting
添加到firebase.json
:
"hosting": {
"rewrites": [
{
"source": "/callMe",
"function": "callMe"
},
]
}
我尝试了httpsCallableFromURL
而不是httpsCallable
:
const addMessage = httpsCallableFromURL(this.functions, 'http://localhost:5001/triggerable-functions-project/us-central1/addMessage');
以下是从应用程序调用Firebase云函数的文档。
以下是错误消息。
Access to fetch at 'https://us-central1-triggerable-functions-project.cloudfunctions.net/addMessage' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.
POST https://us-central1-triggerable-functions-project.cloudfunctions.net/addMessage net::ERR_FAILED
...hundreds of frames...
ERROR Error: Uncaught (in promise): FirebaseError: internal
FirebaseError: internal
at resolvePromise (zone.js:1214:31)
at resolvePromise (zone.js:1168:17)
at zone.js:1281:17
at _ZoneDelegate.invokeTask (zone.js:409:31)
at core.mjs:25298:55
at AsyncStackTaggingZoneSpec.onInvokeTask (core.mjs:25298:36)
at _ZoneDelegate.invokeTask (zone.js:408:60)
at Object.onInvokeTask (core.mjs:25606:33)
at _ZoneDelegate.invokeTask (zone.js:408:60)
at Zone.runTask (zone.js:178:47)
我看了看AngularFire,但放弃了。代码似乎是针对AngularFire 6和Firebase 8的,文档最后一次更新是2021年8月21日。AngularFire 7使用Firebase 9,这是实质性的不同。
下面是我的代码:
- app.component.ts* 在第30行抛出错误。
import { Component } from '@angular/core';
import { getFunctions, httpsCallable, httpsCallableFromURL } from "firebase/functions";
import { initializeApp } from 'firebase/app';
import { getFirestore, setDoc, doc } from "firebase/firestore";
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
firebaseConfig = {
apiKey: "...",
authDomain: "triggerable-functions-project.firebaseapp.com",
projectId: "triggerable-functions-project",
storageBucket: "triggerable-functions-project.appspot.com",
messagingSenderId: "...",
appId: "..."
};
firebaseApp = initializeApp(this.firebaseConfig);
db = getFirestore(this.firebaseApp);
messageText: string | null = null;
functions = getFunctions(this.firebaseApp);
callMe(messageText: string | null) {
console.log("Calling Cloud Function: " + messageText);
const addMessage = httpsCallable(this.functions, 'addMessage');
// const addMessage = httpsCallableFromURL(this.functions, 'http://localhost:5001/triggerable-functions-project/us-central1/addMessage');
addMessage({ text: messageText }) // throws error here
.then((result) => {
console.log(result.data)
});
};
}
- app.component.html* 创建一个表单,您可以键入消息,然后单击
Submit
。
<form (ngSubmit)="callMe(messageText)">
<input type="text" [(ngModel)]="messageText" name="message" placeholder="message" required>
<button type="submit" value="Submit">Submit</button>
</form>
- index.js* 是云函数:
import { initializeApp } from "firebase/app";
import * as functions from "firebase-functions";
import { getFirestore, connectFirestoreEmulator, setDoc, doc } from "firebase/firestore";
const firebaseConfig = {
apiKey: "...",
authDomain: "triggerable-functions-project.firebaseapp.com",
projectId: "triggerable-functions-project",
storageBucket: "triggerable-functions-project.appspot.com",
messagingSenderId: "...",
appId: "..."
};
const firebaseApp = initializeApp(firebaseConfig);
const db = getFirestore(firebaseApp);
connectFirestoreEmulator(db, 'localhost', 8080);
export const addMessage = functions.https.onCall((data, context) => {
try {
const original = snap.data().original;
const uppercase = original.toUpperCase();
return snap.ref.set({ uppercase }, { merge: true });
} catch (error) {
console.error(error);
}
});
- 应用程序模块.ts*
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { environment } from '../environments/environment';
// Angular
import { FormsModule } from '@angular/forms';
// AngularFire
import { provideFirebaseApp, initializeApp } from '@angular/fire/app';
import { provideFirestore, getFirestore, connectFirestoreEmulator } from '@angular/fire/firestore';
import { provideFunctions,getFunctions, connectFunctionsEmulator, httpsCallable, httpsCallableData, httpsCallableFromURL } from '@angular/fire/functions';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
FormsModule,
provideFirebaseApp(() => initializeApp(environment.firebaseConfig)),
provideFirestore(() => {
const firestore = getFirestore();
if (!environment.production) {
connectFirestoreEmulator(firestore, 'localhost', 8080);
}
return firestore;
}),
provideFunctions(() => {
const functions = getFunctions();
if (!environment.production) {
connectFunctionsEmulator(functions, 'localhost', 5001);
}
return functions;
}),
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
1条答案
按热度按时间eoxn13cs1#
我把
httpsCallable
改成了httpsCallableFromURL
。然后GitHub Copilot写了剩下的行。Copilot太棒了!请注意,URL包括服务器位置。本文档说明这可以优化性能。
在函数中,我将
snap
更改为data
。我还去掉了配置和初始化的内容,代码在没有它的情况下运行。添加
hosting
到firebase.json
是不必要的,我把它去掉了。app.component.ts
的样板文件太多。让我们改为引用environment
。