基本上我有 2 個集合“預訂”和“用戶”。“Bookings”集合包含每個用戶創建的所有預訂,“Users”集合顯示有關用戶的資訊。
User: {
name:
uid:
}
Bookings: {
location:
time:
uid:
etc:
}
我有一個 GetBookings() 函式,它檢索“預訂”集合并將其顯示給管理員帳戶。但是,我目前堅持如何向用戶顯示他的預訂。
getBookings() {
var bookings = FirebaseFirestore.instance.collection('bookings');
return bookings.get();
}
我考慮在每個用戶下創建另一個“預訂”集合,但不確定如何將這個新的“預訂”集合與之前的集合鏈接以保留相同的預訂 ID。我嘗試了@Renaud Tarnec 提到的安全規則,但是我可能會弄錯語法,或者在遍歷預訂集合并收到拒絕我們請求的權限期間,它會搶先停止我的 fetchBookings() 函式或用戶可能能夠訪問整個“預訂”集合,無論每個預訂是否有他的 uid。
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Allows users to view their bookings
match /bookings/{booking} {
allow read: if request.auth != null && request.auth.uid == booking.uid;
allow write: if true;
}
}
}
Future<List<BookingModel>> fetchBookings() async {
var bookings = await _bookingRepository.fetchAllBookings();
return bookings.map((snapshot) {
var bookingMap = snapshot.data();
return BookingModel(bookingMap['email'], bookingMap['location'], bookingMap['phoneNumber'],
bookingMap['dateTime'], bookingMap['uid'], bookingMap['dateCreated']);
}).toList();
}
我想知道解決這個問題的專業/工業接受方式是什么。
uj5u.com熱心網友回復:
最好是:在將預訂資料添加到“Booking”集合中時,還需要將其也添加到 user.booking 集合中。
uj5u.com熱心網友回復:
由于bookings集合只能由管理員帳戶訪問,因此在您的情況下(NoSQL 資料庫中的非規范化)的經典解決方案是在集合中創建新預訂時使用云函式在users/{userID}/bookings子集合中創建預訂檔案bookings。
大致如下:
exports.duplicateBooking = functions
.firestore
.document('bookings/{docId}')
.onCreate((snap, context) => {
const userId = ....; // Not clear from your question how you define that. You should probably add it to the booking doc.
const bookingData = snap.data();
return admin
.firestore()
.collection(`users/${userId}/bookings)
.add({
'location': bookingData.location,
'time': bookingData.time,
'email': bookingData.email,
'phoneNumber': bookingData.phoneNumber
});
});
另一種可能性是使用一組允許用戶閱讀自己的預訂bookings的安全規則來保持一個獨特的集合。在這種情況下,請記住,當您撰寫相應的查詢時,規則不是過濾器。
uj5u.com熱心網友回復:
就像我說的,在我看來,對您來說最好的解決方案是在資料庫中設定正確的規則并創建正確的查詢來獲取該資料。
規則:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
match /bookings/{docId} {
allow read: if resource.data.uid == request.auth.uid || isAdmin()
// bellow you can use second part after && but im not sure are it will be null or unassigned this is overenginered so you can just not use condition after &&.
allow update: if resource.data.uid == request.auth.uid && request.resource.data.uid == null || isAdmin()
allow create: if request.auth != null && request.resource.data.uid == request.auth.uid || isAdmin()
allow delete: if isAdmin()
}
}
}
function isAdmin() {
return request.auth.token.admin == true;
}
您需要為用戶進行的查詢:
getBookings() {
// Im not sure are it will work like that in flutter im not a flutter programmer.
// You need to specify using where() method that you want documents with your uid or rules will not allow you to get eny data.
var bookings = FirebaseFirestore.instance.collection('bookings').where('uid', '==', 'user.uid');
return bookings.get();
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/496539.html
