服务器端对 Firestore 的访问和安全规则:Firestore 客户端已关闭

Server-side access to Firestore and security rules: Firestore client closed

提问人:Hank 提问时间:4/9/2021 更新时间:6/1/2021 访问量:673

问:

我在 Firestore 中有数据,我每天都会使用服务器端 Java 代码进行更新。这已经持续了几个月,没有问题。我创建Firestore实例的方式如下。 (我在 Firestore 中有一个服务帐户,其凭据位于 json 文件中。

GoogleCredentials myCredentials = GoogleCredentials.fromStream(new FileInputStream("/myPath/myCredentials.json"));  
    
FirestoreOptions firestoreOptions = FirestoreOptions.getDefaultInstance()
   .toBuilder()
   .setProjectId("myFirestoreProject")
   .setCredentials(myCredentials)
   .build();
Firestore db = firestoreOptions.getService();

Firestore 安全规则不是问题,因为客户端尚未访问 Firestore,因此我无条件地打开了所有涉及的 Firestore 集合以进行读取和写入操作。现在,由于我只希望从 myCredentials.json 中的凭据创建的对 Firestore 的服务器端访问权限具有写入权限,因此我设置了 Firestore 安全规则,如下所示。

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /myCollection/{document=**}{
        allow read;
        allow write: if false;
    }
  }         
}

但是,这些规则会阻止我访问上面创建的 Firestore,而且我也不知道如何设置适当的规则。我了解,如果 Firestore 实例是由

FirebaseOptions options = FirebaseOptions.builder()
   .setCredentials(myCredentials)
   .setDatabaseUrl("https://myFirestoreProject.firebaseio.com")
   .build();
        
FirebaseApp app = FirebaseApp.initializeApp(options, "myFirestoreApp");
Firestore db = FirestoreClient.getFirestore(app);

现在,当我像这样创建数据库并运行更新代码时,我收到错误消息

java.lang.IllegalStateException: Firestore client has already been closed

我不会在这里发布精确的更新代码,因为一方面它很长,另一方面,它与第一种类型的 Firestore 实例创建一起顺利运行。但是,更简单的玩具代码运行良好,因此我检查了第二种类型的Firestore创建确实绕过了安全规则。

我使用 NetBeans,在上面的两种情况下,maven 导入如下:

<dependencies>
   <dependency>
      <groupId>com.google.cloud</groupId>
      <artifactId>libraries-bom</artifactId>
      <version>8.0.0</version>
      <type>pom</type>
      <scope>import</scope>
   </dependency>
   <dependency>
      <groupId>com.google.firebase</groupId>
      <artifactId>firebase-admin</artifactId>
      <version>7.1.1</version>
   </dependency>
</dependencies>>

对这两个 Firestore 实例之间差异的混淆使我产生了两个问题:

  1. 如果我使用最初创建的 Firestore,我是否可以设置安全规则以授予此 Firestore 实例写入权限,同时阻止任何客户端写入访问(例如来自 Android 应用程序)?

  2. 上述有关第二次创建Firestore的错误消息的常见原因是什么,是否有办法阻止Firestore客户端关闭?

java google-cloud-firestore firebase-security 服务器端

评论


答:

0赞 Hank 4/12/2021 #1

如果我通过以下方式创建 Firestore 实例

FirestoreOptions firestoreOptions = FirestoreOptions.newBuilder()
                                       .setCredentials(myCredentials)
                                       .setProjectId("myFirestoreProject")
                                       .build();
                       
           
Firestore db = firestoreOptions.getService();

,则绕过安全规则,并且在写入所有数据之前,此实例不会关闭。

1赞 Álvaro Zamora 6/1/2021 #2

要回答您的第一个问题,如文档中的注释中所述:

“服务器客户端库绕过了所有 Cloud Firestore 安全规则,而是通过 Google 应用程序默认凭据进行身份验证。如果您使用的是服务器客户端库或者 REST 或 RPC API,请确保为 Cloud Firestore 设置 Identity and Access Management (IAM)。

因此,这些规则将仅适用于客户端。您可以通过拒绝对数据库的所有访问来拒绝所有客户端访问。

至于第二个问题,请检查您的代码是否多次初始化或关闭数据库,并确保它遵循文档中的示例。