javascript - 带有转换器的 Firebase 函数在 Set() 上删除文档引用

标签 javascript firebase google-cloud-firestore google-cloud-functions

我有一个计划函数,可以将我的 firestore 中的整数值重置为零。我遇到的问题是,虽然合并集成功(对于指定的属性),但它以某种方式将我的 Organization 文档引用重置为 null。

到目前为止,我已经尝试了以下方法

  • 不将转换器与 Update() 函数一起使用(而不是 Set())。虽然这有效,但它是无类型的,我必须摆脱封装 moment() 到 Date 转换的转换器。
  • 使用 Set() 并简单地传递整个对象。
  user.reference?.withConverter(userConverter).set(user)

这也有效,但它会覆盖整个用户对象,如果用户在定时函数运行时也更新了他的对象,可能会导致并发问题。

我正在寻找一种解决方案,允许我将转换器类与合并 Set() 一起使用。

用户界面如下所示

export interface User extends Document {
  email?: string
  name?: string
  organization?: Organization | null
  numberOfForwards?: number
  lastForwardReset?: moment.Moment
}

它的转换器是这样的

export class UserConverter implements firestore.FirestoreDataConverter<User> {
  toFirestore(user: User): firestore.DocumentData {
    return {
      email: user.email,
      name: user.name,
      organization: user.organization ? user.organization.reference : null,
      number_of_forwards: user.numberOfForwards,
      last_forward_reset: user.lastForwardReset?.toDate()
    }
  }
  fromFirestore(snapshot: firestore.QueryDocumentSnapshot): User {
    const data = snapshot.data()!

    return {
      reference: snapshot.ref,
      email: data.email,
      name: data.name,
      organization: data.organization ? { reference: data.organization } : null,
      numberOfForwards: data.number_of_forwards,
      lastForwardReset: moment(data.last_forward_reset.toDate())
    }
  }
}
export const resetNumberOfForwards = functions.pubsub
  .schedule('every 15 minutes')
  .onRun(async () => {
const reset = (user: User) => {
  console.log(`Resetting ${user.email} from [${user.numberOfForwards}] to [0]`)
  // Claim user reference
  user.reference
    ?.withConverter(userConverter)
    .set({ numberOfForwards: 0, lastForwardReset: Moment() }, { merge: true })
}

为了使部分集起作用,我在文件顶部包含了以下代码片段

firebase.firestore().settings({
  ignoreUndefinedProperties: true
})

最佳答案

我认为这里有两个问题。对于部分 set()您应该使用合并选项,否则它将覆盖文档。

ref.set(data, {merge: true})

此外,在您的 toFirestore 方法中,将 organization 字段设置为 undefined 并让 ignoreUndefinedProperties: true 设置将其删除,或者如果没有给出组织,则根本不要包括它。像这样

toFirestore((numberOfForwards, lastForwardReset, ...user): User): firestore.DocumentData {
  if (user.organization) {
    user.organization = user.organization.reference;
  }
  return {
    ...user,
    number_of_forwards: numberOfForwards,
    last_forward_reset: lastForwardReset?.toDate()
  }
}

我在这里从用户对象中取出了 numberOfForwardslastForwardReset 字段并使用 spread operator将剩余字段复制到返回值,但您也可以保存一个临时对象,修改它,然后返回它。

PS: I know this is old, but it came up in my search so thought I might add an answer still.

关于javascript - 带有转换器的 Firebase 函数在 Set() 上删除文档引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68925136/

相关文章:

JavaScript 如何更改函数内的参数?

javascript - 如何在javascript中取消选择文本框

javascript - 如何在云功能中从firestore获取用户的电子邮件?

java - Firebase 数据库未正确同步

firebase - 在Kotlin中将长字符串转换为Int

javascript - 如何在 Javascript 中深度克隆 XMLDocument 对象?

JavaScript。循环遍历 div 的子集

node.js - Firestore 事务锁会阻止读取吗? (服务端SDK)

swift - Firestore 中是否有相当于 `beginsWith` 的内容?

firebase - Cloud Firestore 安全规则 - 文档中的单个 protected 字段