【问题标题】:How do I create document in Firestore with reliable timestamps?如何在 Firestore 中创建具有可靠时间戳的文档?
【发布时间】:2019-08-14 11:10:16
【问题描述】:

如果无法在 Firestore 服务器本身上设置任何来自客户端 SDK 的 Firestore 时间戳,它们如何被视为有效?

经过身份验证的用户可以破解自己的时间戳,这不是真的吗?如果客户端 sdk 不可靠,那么提供时间戳数据类型的意义何在?这是否意味着我们必须使用 Firebase Admin sdk 在注册时创建用户数据或其他任何需要时间戳的数据?哪个开发人员不会在每个数据集合上加上时间戳?如果是这样,客户端 sdk 的意义何在?显然我错过了一些东西。

我已经从 firebase 客户端 sdk 尝试过这个,没有错误或时间戳;

myFirestoreReference.ref.set({
  userId: firebaseUserCredential.user.uid,
  created: this.$fireStore.FieldValue.serverTimestamp()
})

以上代码成功创建了“userId”,但没有创建“created”时间戳。

【问题讨论】:

  • 您有大约 5 个问题。你能把你的问题缩小到一个问题吗?这是堆栈溢出的约定。或许您可以说明您想要完成的工作,显示未按您预期的方式运行的代码,并说明它在做什么与您的预期不同。
  • 感谢您的回复。这些问题是对相同基本问题的重述,即“如果您不能创建具有可靠时间戳的记录,客户端 sdk 的意义何在?”您可以在添加/编辑时间戳的安全规则中创建一个函数吗?
  • 道格,感谢您的反馈。我决定重命名问题以更准确地反映问题。
  • 以后,请在没有咆哮的情况下提出您的问题,例如“如何创建具有可靠时间戳的记录?”

标签: javascript firebase timestamp google-cloud-firestore


【解决方案1】:

您可以在安全规则中检查时间戳的有效性。此规则要求客户端在写入“foo”集合的文档的created 字段中提供服务器时间戳记令牌:

match /foo/{id} {
    allow write: if request.resource.data.created == request.time;
}

request.time是Firestore收到请求的时间,也是客户端serverTimestamp()生成的token所隐含的值。

【讨论】:

  • 谢谢Doug,我希望使用这段代码,但这意味着您可以通过firebase客户端sdk在客户端设置serverTimestamp(),但似乎并非如此.如果您正在使用通过 firebase 客户端 sdk 设置 serverTimestamp(),请分享。
  • 听起来您有一个新问题要在 Stack Overflow 上发布。 FieldValue.serverTimestamp() 确实有效,而且人们确实使用它。
  • 上面列出的代码是 FireStore 安全规则,而不是用于设置 FieldValue.serverTimestamp() 的 javascript。上面的代码片段假设您已经设置了时间戳。我的问题是如何设置 FieldValue.serverTimestamp()。顺便说一句,文档确实显示了 FireBASE,但没有显示 FireSTORE 对 FieldValue.serverTimestamp() 的使用。那么这个答案是 FireBASE 或 FireSTORE 实现的一部分吗?
  • 好的,这根本不是我阅读您原始问题的方式,也与您留下的 cmets 不一致。如果您的问题只是“如何使用服务器时间戳创建记录”,那么您需要进行大量编辑。此外,您应该准确解释代码中的 this.$fireStore 是什么。实际上,在这一点上,我认为你最好提出一个全新的问题。
  • Doug,这段代码如何解释由于发出请求和到达 Firestore 服务器之间的延迟而导致的时间差异?
【解决方案2】:

我的答案是使用 Firebase Admin sdk 在我的服务器上的 api 中使用以下代码。这是我一直在寻找但迄今为止从未找到的示例。下面列出的代码演示了使用...

Firebase Admin sdk => FireStore

它是可靠的,因为它来自我的服务器,通过 Firebase Admin sdk 而不是 Firebase Client sdk,此外 serverTimestamp() 由 FireStore 服务器设置,而不是我的网络服务器(通过'new Date()')或发出原始请求的客户端计算机。我能够通过从……的例子中推断出这个答案

Firebase 客户端 SDK => FireStore https://firebase.google.com/docs/firestore/manage-data/add-data

Firebase Admin sdk => Firebase 身份验证 https://firebase.google.com/docs/auth/admin/manage-users

var admin = require('firebase-admin');

admin.initializeApp({
  credential: admin.credential.cert({
    projectId: MY_FIREBASE_PROJECT_ID, 
    clientEmail: MY_FIREBASE_CLIENT_EMAIL,
    privateKey: MY_FIREBASE_PRIVATE_KEY,
  }),
  databaseURL: MY_FIREBASE_DATABASE_URL
});


var serverTimestamp = admin.firestore.FieldValue.serverTimestamp()    

admin.firestore().collection('someFireStoreCollection').doc(someFireStoreCollectionId).update({
  someDateField: serverTimestamp
}).then(function() {
  console.log("Successfully updated FireStore");
}).catch(function(error) {
  console.log("Error updating FireStore:", error);
  throw(error)
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-04
    • 2020-05-04
    • 2019-03-23
    • 1970-01-01
    • 2020-08-14
    • 2020-06-23
    • 1970-01-01
    相关资源
    最近更新 更多