仅与 Cloud Firestore 企业版相关。 |
连接要求
与 MongoDB 兼容的 Firestore 客户端需要满足以下要求:
- 驱动程序必须以
load balanced
模式连接。这样可以防止驱动程序尝试了解它们所连接的确切服务器拓扑。 - 驱动程序必须在启用了 SSL 的情况下进行连接。
- 驱动程序必须停用可重试写入。与 MongoDB 兼容的 Cloud Firestore 不支持可重试写入。您无需停用可重试读取,因为它们受支持。
检索连接字符串
数据库连接字符串取决于数据库的 UID、数据库的位置和身份验证机制。以下说明介绍了连接字符串的构成方式。
确切的连接字符串取决于身份验证机制,但基本连接字符串采用以下格式:
mongodb://UID.LOCATION.firestore.goog:443/DATABASE_ID?loadBalanced=true&tls=true&retryWrites=false
您可以通过以下方式之一获取基本连接字符串:
Firebase 控制台
-
在 Firebase 控制台中,前往 Firestore 数据库页面。
- 点击您要进行身份验证的数据库。
- 在探索器面板中,点击 查看更多。
- 选择使用 MongoDB 工具连接。
- 复制连接字符串。
gcloud
使用 gcloud firestore database describe
检索 UID 和位置信息:
gcloud firestore databases describe \ --database=DATABASE_ID \ --format='yaml(locationId, uid)'
将 DATABASE_ID 替换为相应的数据库 ID。
输出包括数据库的位置和 UID。使用此信息构建基本连接字符串。
使用基本连接字符串和以下方法之一对数据库进行身份验证并连接到数据库:
使用用户名和密码 (SCRAM) 进行连接
请按照以下步骤为数据库创建用户凭证并连接到数据库。
准备工作
如需获得创建用户所需的权限,请让您的管理员为您授予数据库的 userCredsAdmin (roles/datastore.userCredsAdmin
) IAM 角色。如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限。
创建用户并连接到数据库
如需为与 MongoDB 兼容的 Cloud Firestore 数据库创建用户,请使用以下方法之一:
Google Cloud 控制台
-
在 Google Cloud 控制台中,转到数据库页面。
- 从数据库列表中选择一个数据库。
- 在导航菜单中,点击 Auth。
- 点击添加用户。
- 输入用户名。
- 为新用户选择一个角色。
-
点击添加。
新用户的密码将显示在确认对话框中。
gcloud CLI
-
如需使用 SCRAM 进行身份验证,您必须先创建用户凭证。使用
gcloud alpha firestore user-creds
命令: 替换以下内容:gcloud alpha firestore user-creds create USERNAME --database=DATABASE_ID
- USERNAME:要创建的用户名。
- DATABASE_ID:数据库 ID。
此命令的输出包括用户的密码。
输出将类似以下内容:
name: projects/PROJECT_NAME/databases/DATABASE_ID/userCreds/USERNAME resourceIdentity: principal: principal://firestore.googleapis.com/projects/PROJECT_NUMBER/name/databases/DATABASE_ID/userCreds/USERNAME securePassword: PASSWORD
-
默认情况下,此新用户凭证没有任何权限。如需拥有数据库的读写权限,请为此特定数据库添加
roles/datastore.user
角色: 替换以下内容:gcloud projects add-iam-policy-binding PROJECT_NAME \ --member='principal://firestore.googleapis.com/projects/PROJECT_NUMBER/name/databases/DATABASE_ID/userCreds/USERNAME' \ --role=roles/datastore.user \ --condition='expression=resource.name == "projects/PROJECT_NAME/databases/DATABASE_ID",title="CONDITION_TITLE"'
- PROJECT_NAME:您的项目的名称。
- PROJECT_NUMBER:项目编号。
- DATABASE_ID:数据库 ID。
- USERNAME:您之前创建的用户名。
- CONDITION_TITLE:相应条件的标题。此条件会将访问权限仅限于此数据库。
Java
本部分提供了一个代码示例,演示了如何使用 Java 管理客户端库创建用户凭证和配置 IAM 政策。该示例使用 Firestore Admin Client 库创建用户名和密码,并使用 Google Cloud Resource Manager 库配置 IAM。
对于 Maven build,您可以使用以下坐标:
com.google.cloud:google-cloud-firestore-admin:3.33.1 com.google.cloud:google-cloud-resourcemanager:1.76.0
预配用户凭证和 IAM 政策:
import com.google.cloud.firestore.v1.FirestoreAdminClient; import com.google.cloud.resourcemanager.v3.ProjectName; import com.google.cloud.resourcemanager.v3.ProjectsClient; import com.google.firestore.admin.v1.CreateUserCredsRequest; import com.google.firestore.admin.v1.GetUserCredsRequest; import com.google.firestore.admin.v1.UserCreds; import com.google.iam.v1.Binding; import com.google.iam.v1.GetIamPolicyRequest; import com.google.iam.v1.GetPolicyOptions; import com.google.iam.v1.Policy; import com.google.iam.v1.SetIamPolicyRequest; import com.google.protobuf.FieldMask; import com.google.type.Expr; public class FirestoreUserCredsExample { /** * Provision user credentials and configure an IAM policy to allow SCRAM authentication into the * specified Firestore with Mongo Compatibility database. */ private static void provisionFirestoreUserCredsAndIAM( String projectId, String databaseId, String userName) throws Exception { UserCreds userCreds = createUserCreds(projectId, databaseId, userName); // Note the password returned in the UserCreds proto - it cannot be retrieved again // after the initial call to the createUserCreds API. System.out.printf( "Created credentials for username: %s:\nIAM principal: %s\nPassword: [%s]\n", userName, userCreds.getResourceIdentity().getPrincipal(), userCreds.getSecurePassword()); // Provision an IAM binding for the principal associated with these user credentials. updateIamPolicyForUserCreds(projectId, databaseId, userName, userCreds); // Emit the password again. System.out.printf( "Successfully configured IAM policy for database: %s, username: %s\n", databaseId, userName); System.out.printf("Please make a note of the password: [%s]\n", userCreds.getSecurePassword()); } /** Provision new user credentials using the FirestoreAdminClient. */ private static UserCreds createUserCreds(String projectId, String databaseId, String userName) throws Exception { FirestoreAdminClient firestoreAdminClient = FirestoreAdminClient.create(); return firestoreAdminClient.createUserCreds( CreateUserCredsRequest.newBuilder() .setParent(String.format("projects/%s/databases/%s", projectId, databaseId)) .setUserCredsId(userName) .build()); } /** Update the IAM policy using the Resource Manager ProjectsClient. */ private static void updateIamPolicyForUserCreds( String projectId, String databaseId, String userName, UserCreds userCreds) throws Exception { try (ProjectsClient projectsClient = ProjectsClient.create()) { ProjectName projectName = ProjectName.of(projectId); // Get the current IAM policy. Policy currentPolicy = projectsClient.getIamPolicy( GetIamPolicyRequest.newBuilder() .setResource(projectName.toString()) .setOptions(GetPolicyOptions.newBuilder().setRequestedPolicyVersion(3).build()) .build()); String role = "roles/datastore.user"; String title = String.format("Conditional IAM binding for %s", userName); String expression = String.format("resource.name == \"projects/%s/databases/%s\"", projectId, databaseId); // Construct an updated IAM policy with an additional binding for the user credentials. Policy.Builder policyBuilder = currentPolicy.toBuilder(); Binding newBinding = Binding.newBuilder() .setRole(role) .setCondition(Expr.newBuilder().setTitle(title).setExpression(expression).build()) .addMembers(userCreds.getResourceIdentity().getPrincipal()) .build(); policyBuilder.addBindings(newBinding); // Update the policy SetIamPolicyRequest request = SetIamPolicyRequest.newBuilder() .setResource(projectName.toString()) .setPolicy(policyBuilder.build()) .setUpdateMask(FieldMask.newBuilder().addPaths("bindings").addPaths("etag").build()) .build(); System.out.println(request); Policy updatedPolicy = projectsClient.setIamPolicy(request); System.out.println("Policy updated successfully: " + updatedPolicy); } } }
使用以下连接字符串通过 SCRAM 连接到数据库:
mongodb://USERNAME:PASSWORD@UID.LOCATION.firestore.goog:443/DATABASE_ID?loadBalanced=true&authMechanism=SCRAM-SHA-256&tls=true&retryWrites=false
替换以下内容:
- USERNAME:用户名。
- PASSWORD:您为此用户生成的密码。
- UID:数据库的 UID。
- LOCATION:数据库的位置。
- DATABASE_ID:数据库 ID。
与 Google Auth 库连接
以下代码示例会注册一个 OIDC 回调处理程序,该处理程序使用 Google Cloud 标准 OAuth 库。
借助此库,您可以使用多种不同类型的身份验证(应用默认凭证、工作负载身份联合)。
这需要将 Auth 库添加为依赖项:
// Maven
<dependency>
<groupId>com.google.auth</groupId>
<artifactId>google-auth-library-oauth2-http</artifactId>
<version>1.19.0</version>
</dependency>
// Gradle
implementation 'com.google.auth:google-auth-library-oauth2-http:1.19.0'
以下代码示例演示了如何连接:
val db = MongoClients.create( clientSettings( "DATABASE_UID", "LOCATION" ).build() ).getDatabase("DATABASE_ID") /** * Creates a connection to a Firestore with MongoDB Compatibility database. * @param databaseUid The uid of the database to connect to as a string. For example: f116f93a-519c-208a-9a72-3ef6c9a1f081 * @param locationId The location of the database to connect to, for example: nam5, us-central1, us-east4 etc... * @param environment Determines whether to try and fetch an authentication credential from the * Compute Engine VM metadata service or whether to call gcloud. */ private static MongoClientSettings.Builder clientSettings( String databaseUid: String String locationId:String ): MongoClientSettings.Builder { MongoCredential credential = MongoCredential.createOidcCredential(null) .withMechanismProperty( MongoCredential.OIDC_CALLBACK_KEY, new MongoCredential.OidcCallback() { @Override MongoCredential.OidcCallbackResult onRequest( MongoCredential.OidcCallbackContext context) { // Customize this credential builder for additional credential types. GoogleCredentials credentials = GoogleCredentials.getApplicationDefault(); return new MongoCredential.OidcCallbackResult( credentials.getAccessToken().getTokenValue(), Duration.between(Instant.now(), credentials.getAccessToken().getExpirationTime().toInstant())); } }, ); return MongoClientSettings.builder() .hosts(listOf(ServerAddress( "$databaseUid.$locationId.firestore.goog", 443))) .credential(credential) .applyToClusterSettings(builder -> builder.mode(ClusterConnectionMode.LOAD_BALANCED)) ).applyToSslSettings(ssl -> ssl.enabled(true)).retryWrites(false); }
替换以下内容:
- DATABASE_UID:您的项目的名称。
- LOCATION:数据库的位置。
- DATABASE_ID:数据库 ID。
从 Google Cloud 计算环境连接
本部分介绍了如何从 Google Cloud 计算环境(例如 Compute Engine 或 Cloud Run 服务或作业)连接到与 MongoDB 兼容的 Cloud Firestore。
从 Compute Engine 虚拟机进行连接
您可以使用 Compute Engine 服务账号对数据库进行身份验证并连接到数据库。为此,请为包含数据库的 Google Cloud 项目创建 IAM 政策。
准备工作
为虚拟机配置用户管理的服务账号:
- 如需在创建虚拟机期间配置服务账号,请参阅创建使用用户管理的服务账号的虚拟机。
- 如需在现有虚拟机上配置服务账号,请参阅更改关联的服务账号。
请参阅配置凭证部分中的说明,完成 Compute Engine 服务账号的 IAM 政策配置。
从 Cloud Run 连接
您可以使用 Cloud Run 服务账号对数据库进行身份验证并连接到数据库。为此,请为包含数据库的 Google Cloud 项目创建 IAM 政策。
准备工作
- 如需为 Cloud Run 配置服务账号,请参阅配置服务身份
- 如需确定已与您的 Cloud Run 服务关联的服务账号,请参阅 gcloud run services describe
请参阅配置凭证部分中的说明,完成 Cloud Run 服务账号的 IAM 政策配置。
配置凭据
如需为服务账号授予读写 Cloud Firestore 的 roles/datastore.user
角色,请运行以下命令:
gcloud projects add-iam-policy-binding PROJECT_NAME --member="SERVICE_ACCOUNT_EMAIL" --role=roles/datastore.user
替换以下内容:
- PROJECT_NAME:您的项目的名称。
- SERVICE_ACCOUNT_EMAIL:您创建的服务账号的邮箱。
构建连接字符串
请使用以下格式构建连接字符串:
mongodb://DATABASE_UID.LOCATION.firestore.goog:443/DATABASE_ID?loadBalanced=true&tls=true&retryWrites=false&authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:gcp,TOKEN_RESOURCE:FIRESTORE
替换以下内容:
- DATABASE_UID:您的项目的名称。
- LOCATION:数据库的位置。
- DATABASE_ID:数据库 ID。
如需详细了解如何检索 UID 和位置,请参阅检索连接字符串。
使用临时访问令牌连接
您可以使用 Google Cloud 的临时访问令牌来运行 mongosh
等诊断工具。您可以使用 gcloud auth print-access-token
通过短期访问令牌进行身份验证。该令牌的有效期为 1 小时。
例如,使用以下命令通过 mongosh
连接到数据库:
mongosh --tls \ --username access_token --password $(gcloud auth print-access-token) \ 'mongodb://UID.LOCATION.firestore.goog:443/DATABASE_ID?loadBalanced=true&authMechanism=PLAIN&authSource=$external&retryWrites=false'
替换以下内容:
- DATABASE_UID:数据库的 UID
- LOCATION:数据库位置
- DATABASE_ID:数据库 ID