我试图在Firestore集合中存储FCM令牌和注册用户之间的关系。为了便于删除无效条目(例如如果不同的用户在同一个客户端上登录),我想给予他们从两个相关值派生的文档ID:当前用户的uid
和fcm token,具体方式如下:
<fcm-token>_<uid>
不幸的是,FCM令牌包含文档ID中不允许的字符。因此,我考虑对FCM令牌进行散列,并发现md5和sha 256是可能的选项,但两者都有不同的问题:
- sha 256作为base64字符串按预期工作,但在某些情况下,结果包含一个
/
,这会破坏文档引用-->不能可靠地使用 - md5作为base64也可以工作,尽管我在测试数据中还没有找到
/
,但我认为它也可以发生(base64规范允许/
,所以我必须期待它)--> can 't use reliably - 将其中任何一个转换为hex而不是base64似乎都不起作用:我得到了
PERMISSION_DENIED: evaluation error
不幸的是,我不知道如何在规则文件中调试哈希函数的输出。
我正在使用Firestore模拟器和@firebase/rules-unit-testing
进行测试。
这是代码,你可以替换相应的行来尝试不同的组合:
测试:
import {
initializeTestEnvironment,
assertSucceeds
} from '@firebase/rules-unit-testing'
import crypto from 'crypto'
let testEnv
before(async () => {
await initializeTestEnvironment({ /* init stuff that works fine in all other cases */})
})
after(async () => {
await testEnv.cleanup()
})
function hash(text) {
return crypto.createHash('sha256').update(text).digest('base64')
// return crypto.createHash('md5').update(text).digest('base64')
// return crypto.createHash('sha256').update(text).digest('hex')
// return crypto.createHash('md5').update(text).digest('hex')
}
describe('Store FCM token' () => {
it('should follow the expected pattern', () => {
const dbAlice = testEnv.authenticatedContext('alice').firestore()
await assertSucceeds(
setDoc(doc(dbAlice, 'tokens', hash('abc123') + '_alice'), {
uid: 'alice',
fcmToken: 'abc123'
})
)
})
})
firestore.rules
:
rules_version = '2';
service cloud.firestore {
match /databases/{databaseId}/documents {
match /{documentId=**} {
allow read, write: if false;
}
match /tokens/{docId} {
function docIdFollowsNamingPattern() {
return docId == hashing.sha256(request.resource.data.fcmToken).toBase64() + '_' + request.resource.data.uid
// return docId == hashing.md5(request.resource.data.fcmToken).toBase64() + '_' + request.resource.data.uid
// return docId == hashing.sha256(request.resource.data.fcmToken).toHexString() + '_' + request.resource.data.uid
// return docId == hashing.md5(request.resource.data.fcmToken).toHexString() + '_' + request.resource.data.uid
}
allow create: if
docIdFollowsNamingPattern();
}
}
}
}
问题:
- 是值得遵循的一般方法。如果没有,你会推荐什么?
- 我如何修复哈希以获得在规则和NodeJS中相同的结果,并且还可以作为文档ID?
1条答案
按热度按时间s5a0g9ez1#
好的我知道了在了解了Firestore规则的
debug()
之后,我了解到本地函数以小写形式输出哈希,而规则中的函数则以大写形式输出。将
.toUpperCase()
添加到本地散列函数解决了这个问题:它适用于md5和sha256。