【问题标题】:How to check if object is instanceof firebase.firestore.FieldValue如何检查对象是否为 instanceof firebase.firestore.FieldValue
【发布时间】:2018-02-14 03:33:30
【问题描述】:

在 firebase js 网页客户端上:

var fv = firebase.firestore.FieldValue;
var sv = fv.serverTimestamp();

sv instanceof fv //true

而在节点中:

var fb = require('firebase-admin');
var fv = fb.firestore.FieldValue;
var sv = fv.serverTimestamp();

sv instanceof fv //false

我不知道为什么会出现这种不一致。我如何判断一个对象是否是 firebase.firestore.FieldValue 的实例?它需要同时适用于 node 和 js web。

编辑

一些上下文。现在,如果我尝试编写类实例,则会引发错误 到 Firestore。为了解决这个问题,我创建了一个实用程序get_database_version 复制 一个类实例到一个可以写入 Firestore 的普通 javascript 对象。 如果该类实例在其中包含某些类型的对象,则 Firestore 视为特殊(如日期和 firebase.firestore.FieldValue's),然后我 只需复制对这些对象的引用即可。

index.js

class Utils {
  static get_database_version(inst, fb) {
    if (Utils.is_function(inst)) { Error(); }

    /* make sure some firebase is defined. it could be client or admin. */
    if (!Utils.is_object(fb) || Utils.is_undefined(fb.firestore)) { Error(); }

    /* if its a basic primitive just return it. */
    if (!Utils.is_null(inst) && !Utils.is_undefined(inst) && !Utils.is_object(inst)) {
      return inst;
    }

    /* return undefined instead of nulls */
    if (Utils.is_null(inst) || Utils.is_undefined(inst)) { return undefined; }

    /* preserve Date instances for firestore writes. */
    if (inst instanceof Date) { return inst; }

    /* preserve fb.firestore.FieldValue instances for firestore writes. */
    if (inst instanceof fb.firestore.FieldValue) { return inst; }

    /* possible return object */
    var obj = {};

    /* inst must be an object at this point, so copy it, stripping it of its class. */
    for (var key in inst) {
      if (!inst.hasOwnProperty(key)) { continue; }

      /* recurse on every value on this object */
      var res = Utils.get_database_version(inst[key], fb);

      /* only add it to the return object if its defined. */
      if (Utils.is_defined(res)) { obj[key] = res; }
    }
    /* i dont want blank objects going to firestore, so make sure it isnt. */
    return Utils.key_count(obj) ? obj : undefined;
  };

  static is_object(value) { return value !== null && (value instanceof Object); };
  static is_function(value) { return typeof value === 'function'; };
  static is_defined(value) { return typeof value !== 'undefined'; };
  static is_undefined(value) { return !Utils.is_defined(value); };
  static is_null(some_var) { return some_var === null; };
  static key_count(some_object) {
    if (!Utils.is_object(some_object)) { throw Error('must pass in an object!'); }
    return Object.keys(some_object).length;
  };
};

module.exports = Utils;

一个样本输入/输出:

var obj = {
  a: undefined,
  b: 55,
  c: {
    d: {},
    e: {
      f: 10
    }
  }
};
console.log(Utils.get_database_version(new Foo(obj), firebase))

//output is an object stripped of Foo
//{
//  b: 55,
//  c: {
//    e: {
//      f: 10
//    }
//  }
//}

【问题讨论】:

  • 您需要在任何环境中执行此检查的具体用例是什么?
  • 现在我无法将类实例写入 Firestore。我必须将它复制到一个裸对象中,以免引发 Firestore 错误。除非该实例包含像 FieldValue 这样的特殊对象,否则这很好。那样的话,在复制过程中,我要问一个对象是否是FieldValue的实例;如果是这样,我不会碰它。这必须适用于两种环境,因为我在前端/后端使用的实用程序类中使用此复制方法。如果您想查看我可以发布的方法。
  • 所以你试图以编程方式查询每个属性以确定它是否可以序列化,并跳过那些不能序列化的?
  • 听起来像。我已经为用法添加了上下文。

标签: javascript firebase google-cloud-firestore firebase-admin


【解决方案1】:

我们正在将FieldValue.delete()FieldValue.serverTimestamp() 的返回值更改为实际上是FieldValue 的实例。这应该是 Firestore Node SDK 下一个版本的一部分。

话虽如此,这是一个实现细节,FieldValue.serverTimestamp()FieldValue.delete() 的返回类型不应影响用户与 Node SDK 交互的方式。我建议您使用自己的类型,而不是依赖我们 SDK 中的任何未记录行为。

说到未记录的行为,一个快速的解决方法是直接比较 FieldValue.serverTimestamp()FieldValue.delete() 返回的对象。 userData === FieldValue.serverTimestamp() 之类的检查保证您可以直接将“userData”传递给 Firestore。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-11
    • 1970-01-01
    • 1970-01-01
    • 2021-10-29
    • 2010-09-27
    相关资源
    最近更新 更多