【问题标题】:Firestore Function DocumentReference.update() called with invalid data. Unsupported field value: a custom object使用无效数据调用 Firestore 函数 DocumentReference.update()。不支持的字段值:自定义对象
【发布时间】:2021-01-01 14:55:35
【问题描述】:

我关注Firebase's instructions,我的功能如下:

import { DataSource, DataSourceConfig } from "apollo-datasource";
import { KeyValueCache } from "apollo-server-caching";
import firebase from "firebase";
import admin from "firebase-admin";
import "@firebase/firestore";
import { Request } from "apollo-server-env";


export class FirebaseDataSource<TContext = any> extends DataSource {
  context!: TContext;
  db: firebase.firestore.Firestore;

  constructor({
    firebaseConfig,
    serviceAccount,
    databaseURL,
  }: {
    serviceAccount: any;
    firebaseConfig: firebase.app.App;
    databaseURL: string;
  }) {
    super();

    this.context;

    if (!firebase.apps.length) {
      firebase.initializeApp(firebaseConfig);
    }

    if (!admin.apps.length) {
      admin.initializeApp({
        credential: admin.credential.cert(serviceAccount),
        databaseURL,
      });
    }

    if (!this.db) {
      this.db = firebase.firestore();
    }

  }

  async initialize(config: DataSourceConfig<TContext & { request: Request }>) {
    this.context = config.context;
  }

  async user_updateRestaurantFavorites(data: {
    uid: string;
    someId: string;
    add: boolean;
  }) {
    const collectionRef = this.db.collection("users");
    const documentRef = collectionRef.doc(data.uid);
    let favorites;
    if (data.add) {
      favorites = await documentRef.update({
        favorites: admin.firestore.FieldValue.arrayUnion(
          data.someId
        ),
      });
    } else {
      favorites = await documentRef.update({
        favorites: admin.firestore.FieldValue.arrayRemove(
          data.someId
        ),
      });
    }
    return favorites;
  }
}

export default FirebaseDataSource;

我对它进行了调试,并且确实通过了 uidaddsomeIdsomeId 是一个字符串,add 是一个布尔值 (true)

当我运行它时,我得到:

使用无效数据调用 Firestore 函数 DocumentReference.update()。不支持的字段值:自定义对象(在文档 users/XXXXXXX 的字段收藏夹中找到)

我只是用一个简单的字符串运行自己的函数。

下面是我的 firestore 的图像,显​​示用户记录确实有一个空数组准备好接受字符串

我做错了什么?

【问题讨论】:

  • 您是否在云函数中执行此代码(您调用admin.firestore.FieldValue.arrayUnion)?
  • 请编辑问题以显示导致问题的完整、最少的代码。尤其是你为分配this.db所做的事情。
  • @DougStevenson,已更新。请注意,我是通过 Apollo Server 触发的
  • @RenaudTarnec,确实如此。通过我的本地主机 apollo 服务器运行的云功能。

标签: javascript node.js firebase google-cloud-firestore


【解决方案1】:

这只是意味着您需要发送查询接收到的确切数据。不允许部分对象

db.collection("users").where("name", "==", somename).limit(1).get().then(query => {
                console.log(query);
                const thing = query.docs[0];
                console.log(thing.data());
                let tmp = thing.data();
                tmp.current_game_play = tmp.current_game_play + 1;
                console.log(tmp);
                thing.ref.update(tmp);
            });

【讨论】:

    【解决方案2】:

    您正在混淆 Web 客户端和管理客户端 SDK。调用 firebase 导出的方法时,不能使用 firebase-admin 导出的 FieldValue 对象。错误消息来自 Web 客户端 SDK,它有效地告诉您您传递了一个它不理解的对象(来自 Admin SDK)。

    您应该选择其中一个,并完全删除您不使用的那个以避免出现问题。如果它在后端运行,您应该只使用 Firebase Admin SDK,并完全跳过网络客户端。如果这样做,则需要使用管理 SDK 分配 this.db,可能为 this.db = admin.firestore()

    【讨论】:

    • 道格,这对我来说是新的,但非常有意义。所以你说如果我正在运行这个功能(以及我没有提到的其他功能)来管理数据库条目(CRUD),那么我最好只使用管理 SDK。正确的?所以我基本上不应该import firebase from "firebase"; 并用admin. 替换每个firebase.,当然设置任何需要设置的东西来正确初始化管理员。我做对了吗?
    【解决方案3】:

    Firebase 只能存储原始类型、映射和相同的数组。在您的情况下,您正在为属性 favorites 保存 admin.firestore.FieldValue.arrayUnion(...) 的结果。

    我的猜测是结果没有返回支持的类型。我之前没用过FieldValue……那是API的正确使用方式吗?

    【讨论】:

    • 我相信 arrayUnion 会生成 Firebase 需要存储的任何内容,否则它们不会出现在他们的文档中。请参阅我原来的问题中的链接。我没有看到什么吗?就像他们建议的那样,我正在向它传递一个数组。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-20
    • 2020-06-13
    • 2021-06-12
    • 2021-05-12
    • 2022-10-23
    • 2021-12-26
    相关资源
    最近更新 更多