簡體   English   中英

如何讓用戶閱讀firebase中documents.uid == user.uid的所有文檔的集合

[英]How to make a user read a collection of all documents where documents.uid == user.uid in firebase flutter

基本上我有 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();
  }

我想知道解決這個問題的專業/工業接受方式是什么。

最好是:在將預訂數據添加到“Booking”集合中時,還需要將其也添加到 user.booking 集合中。

由於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集合。 在這種情況下,請記住,當您編寫相應的查詢時, 規則不是過濾器

就像我說的,在我看來,對您來說最好的解決方案是在數據庫中設置正確的規則並創建正確的查詢來獲取該數據。

規則:

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();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM