英文:
Firebase - addDoc() returns success even when no document was added
问题
新手使用Firebase。我有一个基本的React表单,接收用户的电子邮件并使用addDoc()将其发送到Firestore。
```js
import { initializeApp } from "firebase/app";
import { getFirestore } from "@firebase/firestore";
const firebaseConfig = {
...
};
// 初始化Firebase
export const app = initializeApp(firebaseConfig);
export const db = getFirestore(app)
const emailsCollectionRef = collection(db, "emails");
const addEmail = async (data: { email: string; }) => {
console.log("发送数据到Firebase");
try {
const result = await addDoc(emailsCollectionRef, {email: data!.email});
console.log("已写入文档,ID为:", result.id);
} catch (e) {
console.error("添加文档时出错:", e);
}
}
当我使用addDoc()传递用户的输入时,在try catch中,控制台会显示:
发送数据到Firebase
已写入文档,ID为: YFPaCvSjeBssvUAtdqSh
这很好,但如果我故意试图让它失败,比如更改emailsCollectionRef中集合的名称,例如:
const emailsCollectionRef = collection(db, "NoSuchCollection");
然后再次运行函数,我会得到相同的成功消息。
在Firebase文档中,它说addDoc()
> 返回:
>
> Promise<DocumentReference<T>>
>
> 一个Promise,解析为指向已在后端写入的新创建文档的DocumentReference(请注意,在离线时不会解析)。
在DocumentReference下面说
> DocumentReference是指向Firestore数据库中文档位置的引用,可用于写入、读取或监听该位置。引用位置的文档可能存在,也可能不存在。
如果我想要检查写入是否成功,我必须忽略DocumentReference,并在使用addDoc()后立即执行一个单独的查询,以查看该ID是否实际存在。
我的问题是,是否有一种更好的方法来检查写入是否真的成功,因为显然无法信任DocumentReference?
<details>
<summary>英文:</summary>
New to Firebase. I have a basic React form that takes a user's email and sends it to Firestore using addDoc().
import { initializeApp } from "firebase/app";
import { getFirestore } from "@firebase/firestore"
const firebaseConfig = {
...
};
// Initialize Firebase
export const app = initializeApp(firebaseConfig);
export const db = getFirestore(app)
const emailsCollectionRef = collection(db, "emails");
const addEmail = async (data: { email: string; }) => {
console.log("Sending data to firebase");
try {
const result = await addDoc(emailsCollectionRef, {email: data!.email});
console.log("Document written with ID: ", result.id);
} catch (e) {
console.error("Error adding document: ", e);
}
}
When I pass the user's input using addDoc() in a try catch I get this in the console
Sending data to firebase
Document written with ID: YFPaCvSjeBssvUAtdqSh
Which is fine, but if I purposefully try to make it fail like for example changing the name of the collection in *emailsCollectionRef* e.g.
const emailsCollectionRef = collection(db, "NoSuchCollection");
and run the function again I get the same success message.
In the Firebase docs it says that addDoc()
> Returns:
>
> Promise\<DocumentReference\<T\>\>
>
> A Promise resolved with a DocumentReference pointing to the newly created document after it has been written to the backend (Note that it won't resolve while you're offline).
and under DocumentReference it says
> A DocumentReference refers to a document location in a Firestore database and can be used to write, read, or listen to the location. **The document at the referenced location may or may not exist**.
If I want to check if the write was succesful I have to ignore DocumentReference and immediately after using addDoc() do a separate query to see if that ID actually exists.
My question is, is there a better way to check if the write was actually succesful since DocumentReference obviously cannot be trusted?
</details>
# 答案1
**得分**: 1
集合在您首次编写文档时会自动创建,因此很可能您对不存在的集合进行的`addDoc`调用实际上*创建*了该集合。
如果您想要防止这种情况发生,您可以只允许对数据库中特定已知的集合进行写入,这是通过服务器强制执行的[安全规则](https://firebase.google.com/docs/firestore/security/get-started)来实现的。在这一点上,`addDoc`返回的承诺也将被拒绝/失败。
<details>
<summary>英文:</summary>
Collections are created automatically when you write the first document to is, so quite likely your `addDoc` call with the non-existing collection actually *creates* that collection.
If you want to prevent that, you can only allow writes to specific, known collections in your database's [security rules](https://firebase.google.com/docs/firestore/security/get-started), which are enforced on the server. At that point, the promise returns by `addDoc` will also reject/fail.
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论