在我的项目中,我使用 Firestore REST API 并使用不记名令牌对用户进行身份验证(应用数据库规则)。我现在正在尝试为我的应用程序编写 E2E 测试,但我不知道如何生成令牌。我尝试使用管理 SDK 生成它们,如下所示:
process.env.FIRESTORE_EMULATOR_HOST = 'localhost:8080';
const db = admin.initializeApp({
projectId: PROJECT_ID,
credential: admin.credential.cert(config.fireStore)
});
const token = await db.auth().createCustomToken(uid);
但是生成的令牌不起作用(获得 PERMISSION_DENIED),这并不完全让我感到惊讶,因为配置中的服务帐户是从 Firestore 下载的帐户(我不确定这是否适用于模拟器?)
我还尝试使用以下方法初始化管理 SDK 凭据:
admin.credential.applicationDefault()
,但随后出现以下错误:错误:无法确定服务帐户。确保使用服务帐户凭据初始化 SDK。或者,指定具有 iam.serviceAccounts.signBlob 权限的服务帐户。原始错误:错误:发出请求时出错:getaddrinfo ENOTFOUND 元数据元数据:80。错误代码:ENOTFOUND
任何有关如何执行此操作的帮助或建议将不胜感激。
当您调用 db.auth().createCustomToken(uid) 时,您将获得由您的服务帐户签名的自定义身份验证令牌。这不是 Firebase ID 令牌。它应该从服务器发送到客户端(应用程序、Web 浏览器等),然后客户端可以调用signInWithCustomToken(),以便根据服务器所做的声明在设备上初始化身份验证会话。
完成后,您可以使用 auth.currentUser.getIdToken() 从客户端获取 Firebase ID 令牌
所以基本上在您的测试中,您需要同时使用 Node.js 管理 SDK (firebase-admin) 和 JS 客户端 SDK (firebase) 来模拟用户会话。这应该没问题,因为客户端 SDK 可以在 Node.js 或浏览器环境中工作,但它不是一条光线充足或经过充分测试的路径!
我上面提到的所有内容都适用于针对真实的 Firebase 项目进行测试。但是,如果您使用模拟器,@firebase/testing SDK 会提供用于在测试中模拟身份验证的实用程序。这会生成 Firestore 模拟器接受但在生产中不接受的令牌。所以你可以这样做:
const testing = require('@firebase/testing');
const testApp = initializeTestApp({
projectId: 'your-project-id',
auth: { uid: 'some-uid' }
});
const testAuth = testApp.auth();
const token = testAuth.currentUser().getIdToken();
这里是实现,无需同时使用Firebase admin SDK和Web SDK