skip to Main Content

I want to know the extent that firestore caches security rule evaluations of get() lookups when executing a query or across queries. I feel that the docs, while they do mention cacheing occurs, do not detail the specifics of when it happens or how queries incur particular read costs.

My question is therefore is, on a given query where many documents are requested, will an applicable firestore rule always cache results of get() if that get() is to the same document across the query?

For instance, I have an image collection where each image doc should logically belong to a project (ie project field in the doc). I want an image doc to be secured such that its viewed only by people who are "assigned" to that project, so i structure my data like this:

images collection:

"imgxyz": {
  name: "img1",
  url: "xyz.com",
  snapshot:"bbb",
  project: "aaa",
}
"imgzyx": {
  name: "img2",
  url: "zyx.com",
  snapshot:"bbb",
  project: "aaa",
}

users collection:

"uid1": {
  userName: "img2",
  email: "zyx.com",
  projects: ["aaa","bbb"],
}

then the rules:

service cloud.firestore {
  match /databases/{database}/documents {
  
    function canViewImage() {
    
        let userProjects = get(/databases/$(database)/documents/users/$(request.auth.uid)).data.projects;
        let requestedDocProject = request.resource.data.project;
        return requestedDocProject in userProjects;
    }
  }
}

with the above, how would a query like .where("snapshot", "==", "bbb") perform from a security rules cost standpoint, if query-matched image docs were in the thousands? Would I incur just 1 additional read for the get() lookup of the user, provided to all rule evals of the image doc? or would it be equal to the amount of image docs.

Further, what if the queries were individually called, ie .get("imgxyz") then right after .get("imgzyx"), how would the cacheing work then?

note: i saw this question, but didnt feel that it sufficeintly explained when/why security rules would cache results.

Thank you in advance!

2

Answers


  1. will an applicable firestore rule always cache results of get() if that get() is to the same document across the query?

    Yes.

    with the above, how would a query like .where("snapshot", "==", "bbb") perform from a security rules cost standpoint, if the retrieved image docs were in the thousands?

    No, security rules are not filters. They don’t check all documents. A rule that looks like a filter (when making a query that could match multiple documents) actually just requires that a matching filter be present on the client query, which uses an index to avoid reading every document.

    In more common sense terms: it would be completely unacceptable in terms of query performance guarantees for a rule to actually read and consider every single potentially matching document in a query. That’s why it just considers the query filters.

    Further, what if the queries were individually called, ie .get("imgxyz") then right after .get("imgzyx"), how would the cacheing work then?

    No, there is no caching between queries. The rules have no idea if the underlying data may have changed between queries, so it has to check each document again for each query in order to ensure consistency for each query.

    Login or Signup to reply.
  2. ¿Una regla de Firestore aplicable siempre almacenará en caché los resultados de get() si ese get() es para el mismo documento en toda la consulta?

    Sí.

    Con lo anterior, ¿cómo funcionaría una consulta como .where("snapshot", "==", "bbb") desde el punto de vista del costo de las reglas de seguridad, si los documentos de imágenes recuperados fueran miles?

    No, las reglas de seguridad no son filtros. No revisan todos los documentos. Una regla que parece un filtro (al realizar una consulta que podría coincidir con varios documentos) en realidad solo requiere que esté presente un filtro coincidente en la consulta del cliente, que utiliza un índice para evitar leer cada documento.

    En términos de sentido más común: sería completamente inaceptable en términos de garantías de rendimiento de consultas que una regla realmente lea y considere cada documento potencialmente coincidente en una consulta. Por eso solo considera los filtros de consulta.

    Además, ¿qué pasaría si las consultas se llamaran individualmente, es decir, .get("imgxyz") y luego justo después de .get("imgzyx"), ¿cómo funcionaría entonces el almacenamiento en caché?

    No, no hay almacenamiento en caché entre consultas. Las reglas no tienen idea de si los datos subyacentes pueden haber cambiado entre consultas, por lo que deben verificar cada documento nuevamente para cada consulta para garantizar la coherencia de cada consulta.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search