Paul Nogier
Paul Nogier

Reputation: 31

Firestore add a contition to read only recent data

I'm currently working on a Flutter app using Firebase Cloud Firestore directly from the client.

Actually I have an issue with the read rule of my Firebase Database. In fact I'd like to add a property which will read only the data which is less than 5 minutes old.

So,

These are my current read and write rules :

service cloud.firestore {
  match /databases/{database}/documents {
    match /locations/{allDocuments=**} {
      allow read: if request.time.toMillis() >=
             resource.data.timestamp;
      allow write: if true;
    }
  }
}

This is the function where I read the data in my Flutter code :

void _updateMarkers(List<DocumentSnapshot> documentList) {
    print(documentList);
    markers.clear();
    documentList.forEach(
      (DocumentSnapshot document) {
        final String markerIdVal = 'marker_id_$_markerIdCounter';
        _markerIdCounter++;
        final MarkerId markerId = MarkerId(markerIdVal);
        setState(() {
          GeoPoint pos = document.data['position']['geopoint'];
          var marker = Marker(
              markerId: markerId,
              position: LatLng(pos.latitude, pos.longitude),
              icon: BitmapDescriptor.fromAsset('assets/ticket_point.png'),
              infoWindow:
                  InfoWindow(title: 'Ici à :', snippet: document.data['time']));
          markers[markerId] = marker;
        });
      },
    );

I don't really know how I should proceed, I searched a lot on other topics but didn't get real answers to my question.

Thank you in advance !

Upvotes: 1

Views: 78

Answers (1)

Dan McGrath
Dan McGrath

Reputation: 42018

You got very close on the security rules side. What you are looking for is the global duration namespace, no need for toMillis().

service cloud.firestore {
  match /databases/{database}/documents {
    match /locations/{allDocuments=**} {
      allow read: if request.time - duration.value(5, 's') >= resource.data.timestamp;
      allow write: if true;
    }
  }
}

This is say "if the request is for documents with a timestamp between now and 5 seconds ago, allow it to be read.

Security Rules doesn't act as a filter though, so you will need a query that requests only recent data, and since your client's device likely isn't sync'ed with Google's, you'll also need to consider something like a Cloud Function to retrieve a current time. [You could also consider Google's Public NTP service, but it has no SLA].

Upvotes: 1

Related Questions