使用转换器的Firebase函数在调用set()方法时会清除文档引用。

3

我有一个定时函数,用于将我的firestore中的整数值重置为零。我遇到的问题是,虽然合并设置成功(对于指定的属性),但它会将我的Organization文档引用重置为null。

目前为止,我尝试了以下方法:

  • 不使用转换器与Update()函数(而不是Set())。虽然这可以工作,但它是不带类型的,并且我必须放弃封装moment()到Date转换的转换器。
  • 使用Set()并简单地传递整个对象。
  user.reference?.withConverter(userConverter).set(user)

这个也可以工作,但会覆盖整个用户对象,在定时函数运行时可能会导致并发问题。

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

User接口如下所示:

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
})
1个回答

1
我认为这里有两个问题。对于部分set(),您应该使用合并选项,否则它会覆盖文档。请注意保留HTML标签。
ref.set(data, {merge: true})

此外,在你的 toFirestore 方法中,要么将 organization 字段设置为 undefined 并让 ignoreUndefinedProperties: true 设置将其删除,要么如果未提供 organization,则完全不包括它。类似这样:
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字段,使用扩展运算符将剩余字段复制到返回值中,但你也可以保存一个临时对象,修改它,并返回该对象。

PS:我知道这篇文章有点旧了,但是它出现在我的搜索结果中,所以我想仍然添加一个答案。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接