Home > Enterprise >  Cannot access subcollection in Firestore with Firebase Rules
Cannot access subcollection in Firestore with Firebase Rules

Time:10-16

I am trying to write in a subcollection TopUp on Temp's document, the Temp collection document has its own write rules that and is different from TopUp document. I am expecting that this is supported?

    // The wildcard expression {deviceId} makes the deviceId variable available in rules.
    // Store client's temporary data, use for checking serial number using Firebase Rules.
    match /Temp/{deviceId} {
    
      // Authentication is required.
      allow create, update: if request.auth != null && 
      // Device can only modify their own data.
      request.auth.uid == deviceId;
      
      // No reading or deletion of data is allowed in clients (mobile and web).
      allow read, delete: if false;
    
    }
    
    // The wildcard expression {userId} makes the userId variable available in rules.
    // Store client's temporary data, use for checking top up with Cloud Functions.
    match /Temp/{userId}/TopUp/{docId} {
    
      // Authentication is required.
      allow create: if request.auth != null && 
      // Cashiers can only top up devices that are assigned to them.
      // Make sure the uid of the requesting user (cashier) matches of the device's cashier_id.
      request.auth.uid == get(/databases/$(database)/documents/Devices/$(userId)).cashier_id;
      
      // No reading, update, or deletion of data is allowed in clients (mobile and web).
      allow read, update, delete: if false;
    
    }

Sample code

firestore.collection("Temp")
            .doc($('input:hidden[name=zyx]').val())
            .collection("TopUp")
            .doc()
            .set({
                cash: $("#cashField").val(),
                topUp: $("#topUpField").val()
            },{ merge: true }).then((doc) => {
                $('#cashField').val("")
                $('#topUpField').val("")
                Swal.fire({
                    title: "Success!",
                    text: "Top up should reflect now on the device.",
                    type: "success"
                }).then(function () {
                    hideDevicesLoading()
                    $("#deviceTopUpModalDetail #closeModule").click()
                    fetchData("deviceList", DEVICES)
                });
            }).catch((error) => {
                showError(error.message)
                hideDevicesLoading()
            });

CodePudding user response:

The result get() itself does not contain the document's data. The data property is an object that contains it. Try .data.cashier_id as shown below:

get(/databases/$(database)/documents/Devices/$(userId)).data.cashier_id
  • Related