[英]`setDoc` write to Firestore from TypeScript Functions messes up directory structure on `npm run build`
Transpiling TypeScript creates a new, incorrect directory structure when a Firebase Function writes to Firestore with setDoc
or updateDoc
.当 Firebase 函数使用setDoc
或updateDoc
写入 Firestore 时,转译 TypeScript 会创建一个新的、不正确的目录结构。
This code transpiles and runs correctly:此代码可以正确转译和运行:
index.ts索引.ts
import * as functions from "firebase-functions";
export const MakeUppercase = functions.firestore.document('Messages/{docId}').onCreate((snap, context) => {
try {
const original = snap.data().original;
const uppercase = original.toUpperCase();
return snap.ref.set({ uppercase }, { merge: true }); // writes to the same document
} catch (error) {
console.error(error); // emulator always throws an "unhandled error": "Your function timed out after ~60s."
return 0;
}
});
The first time the function is transpiled in a new directory the transpiler makes this directory structure:函数第一次在新目录中转译时,转译器会生成以下目录结构:
myproject
├── environments
│ └── environment.ts
├── functions
│ ├── lib
│ │ ├── index.js
│ │ ├── index.js.map
│ ├── node_modules
│ ├── package-lock.json
│ ├── package.json
│ ├── src
│ │ ├── index.ts
│ └── tsconfig.json
That directory structure is correct.该目录结构是正确的。 The main
in package.json
is package.json
中的main
是
lib/index.js
Let's change the code a little and use setDoc
to write to a different directory in Firestore:让我们稍微更改一下代码并使用setDoc
写入 Firestore 中的不同目录:
index.ts索引.ts
import * as functions from "firebase-functions";
import { initializeApp } from "firebase/app";
import { getFirestore, setDoc, doc } from "firebase/firestore";
import { environment } from '../../environments/environment';
const firebaseApp = initializeApp(environment.firebase);
const firestore = getFirestore(firebaseApp);
export const MakeUppercase = functions.firestore.document('Messages/{docId}').onCreate((snap, context) => {
try {
const original = snap.data().original;
const uppercase = original.toUpperCase();
return setDoc(
doc(firestore, 'AnotherCollection', context.params.docId),
{ uppercase }, { merge: true }
);
} catch (error) {
console.error(error); // emulator always throws an "unhandled error": "Your function timed out after ~60s."
return 0;
}
});
I transpile the function with npm run build
in the functions
directory.我在functions
目录中使用npm run build
编译函数。 The directory structure changes to:目录结构更改为:
myproject
├── environments
│ └── environment.ts
├── functions
│ ├── lib
│ │ ├── environments
│ │ │ ├── environment.js
│ │ │ └── environment.js.map
│ │ ├── functions
│ │ │ └── src
│ │ │ ├── index.js
│ │ │ ├── index.js.map
│ │ ├── index.js
│ │ ├── index.js.map
│ ├── node_modules
│ ├── package-lock.json
│ ├── package.json
│ ├── src
│ │ ├── index.ts
│ └── tsconfig.json
The transpiler added three new directories and four new files.转译器添加了三个新目录和四个新文件。 It's exposing my apiKey
and other credentials.它暴露了我的apiKey
和其他凭据。 To make the new function run I changed main
to为了使新功能运行,我将main
更改为
lib/functions/src/index.js
Now the new code runs but it won't write to Firestore.现在新代码运行了,但它不会写入 Firestore。 I'm getting PERMISSION_DENIED: Missing or insufficient permissions.
我收到PERMISSION_DENIED: Missing or insufficient permissions.
errors.错误。 Here's my rules:这是我的规则:
firestore-rules Firestore 规则
rules_version = "2";
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write;
}
}
}
Don't worry, those rules are for the emulator, not for production.别担心,这些规则适用于模拟器,不适用于生产。
A couple more weird things.还有一些奇怪的事情。 Visual Studio Code shows a single directory functions/src
, not two, nested directories. Visual Studio Code 显示单个目录functions/src
,而不是两个嵌套目录。 (MacOS shows two nested directories.) (MacOS 显示两个嵌套目录。)
I can deploy the new function to Cloud Functions with firebase deploy
but gcloud functions deploy
won't deploy the function.我可以使用 firebase deploy 将新函数部署到 Cloud Functions,但firebase deploy
gcloud functions deploy
不会部署该函数。 It throws an error that it can't find index.js
:它抛出找不到index.js
的错误:
lib/functions/src/index.js does not exist;
What is going on here???这里发生了什么??? To test this I spun up four new Firebase Functions directories.为了对此进行测试,我创建了四个新的 Firebase Functions 目录。 I tried different functions.我尝试了不同的功能。 It happens every time I use setDoc
or updateDoc
, and doesn't happen if the code doesn't include setDoc
or updateDoc
.每次我使用setDoc
或updateDoc
时都会发生,如果代码不包含setDoc
或updateDoc
则不会发生。
Here's my tsconfig.json
:这是我的tsconfig.json
:
tsconfig.json tsconfig.json文件
{
"compilerOptions": {
"module": "commonjs",
"noImplicitReturns": true,
"noUnusedLocals": true,
"outDir": "lib",
"sourceMap": true,
"strict": true,
"target": "es2017"
},
"compileOnSave": true,
"include": [
"src"
]
}
Thanks, @Doug Stevenson!谢谢,@Doug Stevenson! What I'm reading in your comment is that Firebase Cloud Functions can't use the Firebase 9 syntax setDoc
and updateDoc
for Firestore, and uploadString
etc. for Storage.我在您的评论中读到的是 Firebase Cloud Functions 不能将 Firebase 9 语法setDoc
和updateDoc
用于 Firestore,以及uploadString
等用于存储。 We have to use the old school Firebase syntax, like this:我们必须使用老式的 Firebase 语法,如下所示:
index.js索引.js
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
export const MakeUppercase = functions.firestore.document('Messages/{docId}').onCreate(async (snap: any, context: any) => {
try {
const original = snap.data().original;
const uppercase = original.toUpperCase();
await admin.firestore().collection('AnotherCollection').add({uppercase: uppercase});
return uppercase;
} catch (error) {
console.error(error); // emulator always throws an "unhandled error": "Your function timed out after ~60s."
return 0;
}
});
That transpiled without creating new directories or files, and ran without a problem.在没有创建新目录或文件的情况下进行了编译,并且运行没有问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.