shmibbles
shmibbles

Reputation: 418

how to convert a set into a list in firestore security rules?

i need to get an item from a set returned from

resource.data.diff(request.data).changedKeys()

so, is there a way to get an item from a set, or turn a set into a list to get an item?

I don't need to compare any values, so i don't need hasOnly() or any related functions, i need to get one of the values in a set, any way to do this?

Upvotes: 4

Views: 534

Answers (4)

catta
catta

Reputation: 11

I have found a stupid workaround in case we generated the set from a mapDiff. We take the keys of the 2 maps as 2 lists and remove one from the other. In my case I had only 1 key difference by design:

let newKey = request.resource.data.keys().removeAll(resource.data.keys())[0];

this is the key that would be in the set:

request.resource.data.diff(resource.data).addedKeys();

Now you can access the value of the map with:

request.resource.data[newKey]

hoping that the order of the lists is the same / removeAll removes all the values regardless of the position.

Upvotes: 1

m3dtem
m3dtem

Reputation: 9

ok, there is no Set accessor, but if you know for a fact that your Set has exactly one value, or you want to access any value of the Set, and there is a list that includes this value, then you can use this approach to access the Set value (it should work even if you list is unsorted and has repeated values):

let s = 0;
let e = list.size() - 1;
let mid = 0; let firstHalf = false;


mid = int((s+e)/2);
firstHalf = list[s:mid].toSet().hasAny(inputSet);
s = firstHalf ? s : mid;
e = firstHalf ? mid : e;

just repeat the last 4 lines ~10 to 20 times, and either list[s] or list[e] will have the value in inputSet

Upvotes: 0

l1b3rty
l1b3rty

Reputation: 3644

I raised a ticket to Firebase support to make Set's values accessible as soon as Set was added to the API. Still waiting...

The workaround I use is request.writeFields, which contains all the fields that are written to for a given create/update.

Note:

  • request.writeFields is deprecated and may be removed (crazy in my opinion when there is no other workaroung available)

  • For nested fields it will give you the full path for each field For instance if you update the following fields in your doc:

    {
      A              // UPDATED
      B: {
       BA
       BB            // UPDATED
      }
      C: {
        CA: {
          CAA        // UPDATED
        }
        CB
      }
    }
    

=> request.writeFields = ['A', 'A.BB', 'C.CA.CAA']

Upvotes: 4

Doug Stevenson
Doug Stevenson

Reputation: 317292

The complete list of things you can do with Set is in the linked API documentation. Same thing with List.

As you can see, there are no element accessors available with Sets. All you can do is check size and existence, and manipulate contents.

For Lists, you must know the index of the element to get something. If you don't know the index, then you can't access it.

Neither collection offers a function to "get an arbitrary, unnamed, unindexed item".

Upvotes: 2

Related Questions