firebase / firebase/firebase-admin-node

[FR] Blocking function for firestore document modification at create/update/delete

Đang mở
#2,077 1 bình luận 0 reaction 0 người được giao Xem trên GitHub
needs-triage type: feature request
Ngôn ngữ chính
TypeScript
Star
1.7k
Fork
419
Merge trung bình
3 ngày 10 giờ
Pull request đã merge (30 ngày)
16

Mô tả

**Is your feature request related to a problem? Please describe.**
There are many situation that we just not only want to protect document from being written (which could be done by security rules), but to also inject data into document or modified something complicate or written data by some logic on the server

For example, user might modified some field about their profile, such as their name or email. And then we decide that we want to index all their named profile into array of lowercase text chunks. So we could do text search with firestore `in` query

But utilizing `onWrite` function to written complicate checking logic and update same document 2 times every time user change their profile is not ideal. Especially it was admittedly risking infinite loop

**Describe the solution you'd like**
Taken idea from firebase auth blocking function, firestore should also have blocking function, `beforeWrite` function that provide the same parameter as `onWrite` function but need to return document, or throw exception to cancel writing document

Taken example from https://firebase.google.com/docs/firestore/extend-with-functions#reading_and_writing_data

```js
// Listen for updates to any `user` document.
exports.countNameChanges = functions.firestore.document('users/{userId}').onUpdate((change, context) => {
// Retrieve the current and previous value
const data = change.after.data();
const previousData = change.before.data();

// We'll only update if the name has changed.
// This is crucial to prevent infinite loops.
if (data.name == previousData.name) {
return null;
}

// Retrieve the current count of name changes
let count = data.name_change_count;
if (!count) {
count = 0;
}

// Then return a promise of a set operation to update the count
return change.after.ref.set({
name_change_count: count + 1
}, {merge: true});
});
```

Could be changed into

```js
// Listen for updates to any `user` document.
exports.countNameChanges = functions.firestore.document('users/{userId}').beforeWrite((change, context) => {
// Retrieve the current and previous value
const data = change.after.data();
const previousData = change.before.data();

if (data.name != previousData.name) {
data.name_change_count = (previousData.name_change_count || 0) + 1;
}

data.lastUpdate = FieldValue.serverTimestamp(); // now we can also index updateTime without exposing metadata updateTime
// Must return the data
return data;
});
```

**Describe alternatives you've considered**
Alternatively this could be done by the security rule directly if we have security rule v3 with more syntax to allow set feature

**Additional context**
I have not sure if it (and should it) allow blocking function in firestore with async function and transaction. Maybe it should be sync function but can request for dependency document

```js
// Listen for updates to any `user` document.
exports.countNameChanges = functions.firestore.document('users/{userId}')
.requireDocs((userId) => ["userAdditionalProfiles/" + userId,"admins/" + userId]) // array of `collection/docId` to request some documents from other collections
.beforeWrite((change, context,[profile,admin]) => {
// Retrieve the current and previous value
const data = change.after.data();
const previousData = change.before.data();

if (data.name != previousData.name) {
data.name_change_count = (previousData.name_change_count || 0) + 1;
}

if(admin.exist && data.adminLevel != admin.get("level")) {
data.adminLevel = admin.get("level"); // always sync user with admin level for indexing and querying
}

// Must return the data in sync
return data;
});
```

Or maybe providing transaction to write multiple document too?

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Hướng nghiên cứu

Issue đề cập đến các trình kích hoạt tài liệu Firestore, các API onWrite và beforeWrite được đề xuất, cùng tài liệu Firebase Functions, nhưng không có tệp repository hoặc test nào. Trước tiên, hãy xem xét các điểm vào hiện có của trình kích hoạt Firestore và tài liệu được liên kết, sau đó làm rõ việc hỗ trợ create/update/delete, công việc bất đồng bộ, giao dịch và hủy. Công việc được coi là hoàn tất khi phạm vi API và các tiêu chí chấp nhận đã được thống nhất.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
firebase, javascript
Lĩnh vực
backend, databases
Loại issue
Tính năng
Độ khó
5/5
Thời gian dự kiến
Hơn một tuần
Mức độ hoạt động
Đình trệ
Độ rõ ràng
Cần làm rõ
Mức phù hợp với người mới
25/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.