Я использую Firebase в своем проекте Android, у меня есть коллекция пользователей в базе данных Cloud Firestore, пользователи могут обновлять только некоторые поля, но могут читать все, я знаю, что невозможно защитить часть документа от обновляется, и правила безопасности могут применяться только ко всему документу, поэтому я искал об этом, и единственное решение, которое я нашел, - это создать вложенную коллекцию внутри пользовательского документа, создать новый документ внутри этой вложенной коллекции и, наконец, поместить поля, которые я хочу защитить там, тогда я могу легко защитить этот документ, применяя этот код в разделе правил безопасности:
match /users/{userId}/securedData/{securedData} {
allow write: if false;
allow read: if true;
}
Так что теперь никто не может писать эти поля, но каждый может читать, и это именно то, что я хочу, но позже я обнаружил, что мне нужно запрашивать пользователей на основе полей внутри подколлекции, так называемой коллекции. групповой запрос, который на данный момент не поддерживается, поэтому я остановился на двух решениях:
- Извлеките всех пользователей и отфильтруйте их на стороне клиента, но это увеличит число считываемых документов, потому что я запрашиваю все документы собрания пользователей + дополнительный документ для подсборки, прочитанный для каждого пользователя, чтобы получить необходимое поле для фильтрация пользователей.
Вместо создания вложенной коллекции в пользовательском документе и возникновения этих проблем, просто сохраните все поля в документе верхнего уровня (пользовательский документ), позволяя пользователям обновлять любое поле.
match /users/{userId} {
allow update, read: if true;
allow create, remove: if false;
}
Но создайте облачную функцию (onUpdate) для прослушивания обновлений пользовательских документов и
обнаруживать изменения в полях, которые не могут быть изменены пользователем, поэтому
если пользователь попытался изменить эти поля, я могу обнаружить это и вернуть измененным полям их прежние значения, например:
export const updateUser = functions.firestore
.document('users/{userId}')
.onUpdate((change, context) => {
const previousValue = change.before.data().securedField;
const newValue = change.after.data().securedField;
if (previousValue !== newValue) {
return db.collection('users')
.doc(context.params.userId)
.update({ securedField: previousValue });
}
});
Безопасно ли второе решение? какое лучшее решение для этого? или какие-то другие решения?