firebase 将FCM标记转换为在Firestore中用作文档ID的表示形式

zqdjd7g9  于 2023-05-07  发布在  其他
关注(0)|答案(1)|浏览(136)

我试图在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?
s5a0g9ez

s5a0g9ez1#

好的我知道了在了解了Firestore规则的debug()之后,我了解到本地函数以小写形式输出哈希,而规则中的函数则以大写形式输出。
.toUpperCase()添加到本地散列函数解决了这个问题:

function hash(text) {
  return crypto.createHash('sha256').update(text).digest('hex').toUpperCase()
  // return crypto.createHash('md5').update(text).digest('hex').toUpperCase()
}

它适用于md5和sha256。

相关问题