哪些变量可用作 Firestore 规则匹配语句中的 "wildcards"?

What variables are available for use as "wildcards" in a Firestore Rules Match Statement?

https://firebase.google.com/docs/reference/security/storage 中指定了您可能想要声明以保护 Firestore 集合中的文档的规则语法的语法。但这描述了 Google 云存储的更广泛上下文,因此,当您尝试将这些专门用于 Firestore 应用程序时,文档似乎有点不透明。

用于指定应用规则的集合 myCollection 中的文档子集的 match 语句通常采用以下形式:

    match myCollection/{wildcard}

我的问题是“哪些变量可用作通配符?”。根据上面引用的 Google 文档,“通配符变量是通过将变量用大括号括起来在路径中声明的:{variable}。该变量可以在匹配语句中作为字符串访问。”

我现在明白了,如果 myCollection 包含一个名为 email 的字段,则匹配语句的形式为

    match myCollection/{email}

将允许我指定一个规则,该规则将应用于其 documentId 为电子邮件字段指定值的文档。在这种情况下,仅允许登录用户读取他们自己在 myCollection 中的记录的规则将采用以下形式:

    match myCollection/{email}
        allow read : if request.auth != null && request.auth.token.email == email;

其中电子邮件是用户在 myCollection

中提交的电子邮件地址

但假设电子邮件未被用作识别 myCollection 记录的唯一键 - 即其他字段识别文档,并且用户可能在 myCollection 中有许多用他们的电子邮件标记的记录?这肯定是更可能的情况,但 Google 文档似乎没有提供任何线索来说明如何指定匹配项来涵盖这种情况。

之前在 的 Whosebug 问题已将我引向关键字 doc。这使我能够指定一个更通用的规则,该规则可以应用于具有特定电子邮件值的集合中的所有记录:

    match /myCollection/{doc} {
      allow read : if request.auth != null && 
                      request.auth.token.email == resource.data.email;
}

这里有两个概念对我来说是新的(至少在 Firestore 规则的上下文中):首先是关键字 doc,其次是 resource.data.email 结构,它使我的规则能够访问文档领域。谁能告诉我这些构造在哪里记录,以及“通配符”概念是否还有更多“问题”(我已经知道文档=** 一个)。

match myCollection/{wildcard} - 此规则告诉 firebase 匹配 myCollection 集合中的所有文档。本质上,它表示匹配所有匹配此路径的文档 myCollection/*

上面的

wildcard 只是一个保存文档路径(星号路径)的变量。这个变量可以是任何东西(保留字符串除外)。如果这是你的路径:

  1. 'myCollection/tests',则通配符变量为'tests';
  2. 'myCollection/test@email.com',则通配符变量为'test@email.com'

wildcard 只是一个占位符,用于匹配此路径的任何内容:myCollection/*。除了通配符,您可以使用任何东西,例如电子邮件(myCollection/{email},这里的电子邮件成为保存文档路径的变量)。

resource.data 是正在获取的数据。因此,如果您的数据具有 'email' 字段,则 resource.data.email 始终包含电子邮件字段数据(无论通配符变量是什么)。 不要使用保留字符串,例如 'resource' 作为通配符变量。

what variables are available for use as wildcards?

任何放在花括号中的变量都会成为通配符变量。它只是保存文档路径。这不是一个特殊的字符串。

更新@MartinJ.

对于自动生成的 ID。假设这是您的文档路径 myCollection/1s6SUqi8M6sC6DZdTKjt,(1s6SUqi8M6sC6DZdTKjt 是自动生成的)

match /myCollection/{email} {
  allow read : if email == '1s6SUqi8M6sC6DZdTKjt'; // true because
  // email variable holds the value '1s6SUqi8M6sC6DZdTKjt'
}
match /myCollection/{doc} {
  allow read : if doc == '1s6SUqi8M6sC6DZdTKjt'; // true because
  // doc variable holds the value '1s6SUqi8M6sC6DZdTKjt'
}
match /myCollection/{Whosebug} {
  allow read : if Whosebug == '1s6SUqi8M6sC6DZdTKjt'; // true 
  // because Whosebug variable holds the value '1s6SUqi8M6sC6DZdTKjt'
}
// It does not matter what we use as wildcard variable (we can even 
// use MartinJ), it will always hold the value of '1s6SUqi8M6sC6DZdTKjt' 
// (doc id if the path matches).
// As @Frank said, these are simply variables, not keywords. You 
// can call it anything and it will have the value of doc path.
}

如果这是您的文档路径 sales/2K5CwGU9ZWwNoO9efyuv/payments/40ciObsicEntBZParkon(自动生成的文档 ID)

match /sales/{doc=**} {
  allow write: if doc == '2K5CwGU9ZWwNoO9efyuv/payments/40ciObsicEntBZParkon';
  // this will be true because doc=** (**with asterisks**) matches 
  // everything after sales
}
match /sales/{saleId} {
  match /payment/{paymentId} {
    allow write: if saleId == '2K5CwGU9ZWwNoO9efyuv' && paymentId == '40ciObsicEntBZParkon';
    // this will be true because saleId holds the value 
    // '2K5CwGU9ZWwNoO9efyuv' and paymentId holds this value '40ciObsicEntBZParkon'
  }
}