简体   繁体   English

保存后检索 Cloud Firestore `timestamp` 值

[英]Retrieving Cloud Firestore `timestamp` value after save

Let's say I'm adding some data to Cloud Firestore:假设我要向 Cloud Firestore 添加一些数据:

import { collection, addDoc, serverTimestamp } from 'firebase/firestore'; 

const ref = await addDoc(collection(db, 'posts'), {
  createdAt: serverTimestamp(),
  modifiedAt: null,
  title: 'A Title',
});

I have rules enforcing createdAt should equal request.time and never be updated, modifiedAt should be null on create but equal to request.time on update, and title should be a string.我有规则强制执行createdAt应该等于request.time并且永远不会更新, modifiedAt在创建时应该是null但在更新时等于request.time ,而title应该是一个字符串。

The problem arises when I try to update this document:当我尝试更新此文档时出现问题:

import { doc, updateDoc } from 'firebase/firestore';

await updateDoc(ref, {
  createdAt: ???, // what goes here?
  modifiedAt: serverTimestamp(),
  title: 'A Title',
});

I need createdAt to be that initial server timestamp value (as a Date object).我需要createdAt作为初始服务器时间戳值(作为Date对象)。 I can't just put serverTimestamp() because Firestore will try to update that field to the new request.time value and rule enforcement will fail.我不能只放置serverTimestamp() ,因为 Firestore 会尝试将该字段更新为新的request.time值,规则执行将失败。 I can't do a partial update (by omitting createdAt ) because I'm using a client-side ORM (Ember Data), which isn't capable of handling partial updates like this.我无法进行部分更新(通过省略createdAt ),因为我使用的是客户端 ORM(Ember 数据),它无法像这样处理部分更新。

Is there a way to retrieve whatever that initial serverTimestamp value became after calling addDoc , without making a second request immediately after addDoc to retrieve the document we just created?有没有一种方法可以检索调用addDoc后初始serverTimestamp值变成的任何值,而无需在addDoc之后立即发出第二个请求来检索我们刚刚创建的文档? It seems unnecessary to make that second request, since I already have all the data (sans the timestamp values).似乎没有必要提出第二个请求,因为我已经拥有所有数据(没有时间戳值)。 I'm basically just trying to avoid adding a second request app-wide every time a new record is created.我基本上只是试图避免在每次创建新记录时在整个应用程序范围内添加第二个请求。

An updateDoc operation (unlike an addDoc operation or the default setDoc operation) will only overwrite the keys that you actually specify. updateDoc操作(不同于addDoc操作或默认的setDoc操作)只会覆盖您实际指定的键。 So to leave createdAt as-is, simply omit it.因此,要按原样保留createdAt ,只需将其省略即可。

await updateDoc(ref, {
  modifiedAt: serverTimestamp(),
  title: 'A Title',
});

To pluck the key from your CRM, use delete on the key.要从您的 CRM 中提取密钥,请对密钥使用delete

const dataToUpdate = {
  createdAt: "somevalue",
  modifiedAt: serverTimestamp(),
  title: 'A Title'
}
delete dateToUpdate.createdAt;

await updateDoc(ref, dataToUpdate);

Additionally, adding a getDoc immediately after isn't as.network expensive as you think it is.此外,紧随其后添加getDoc并不像您想象的那样昂贵。 If your application uses that document anywhere in your application (either listening to the document itself or its parent collection), your client app will be notified and given the updated data to store in its local cache regardless of if you need it immediately after adding it.如果您的应用程序在您的应用程序的任何地方使用该文档(监听文档本身或其父集合),您的客户端应用程序将收到通知并将更新的数据存储在其本地缓存中,无论您是否在添加后立即需要它.

const ref = await addDoc(collection(db, 'posts'), {
  createdAt: serverTimestamp(),
  modifiedAt: null,
  title: 'A Title',
});

const snapshotWithServerTimestamps = await getDoc(ref);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM