时间戳不适用于Firebase功能测试

时间:2019-11-14 21:58:59

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

我正在使用firebase-admin 8.6.0和firebase-functions-test 0.1.6,它在测试中支持Firestore时间戳(自0.1.5 https://github.com/firebase/firebase-functions-test/releases起),但在以下情况下仍收到错误消息:尝试与getServiceHub().signInitialTransaction(txBuilder, Arrays.asList(pkOfAcc1, pkOfAcc2, pkOfAcc3); 一起使用。

有人可以帮助我理解实现中的错误吗?

test.firestore.makeDocumentSnapshot

我无法使用三个时间戳选项中的任何一个。我尝试过在https://github.com/firebase/firebase-functions-test/pull/28的@ the0rem中学习后者,但无济于事。我总是会收到此错误:

  

无法将[object Object]编码为Firestore值。本地测试尚不支持Firestore地理位置。

1 个答案:

答案 0 :(得分:2)

当我看到您的问题时,我感到很兴奋,因为我也面临着同样的问题。无论如何,这就是我最终解决它的方法。这是我从Firestore数据库中保存的JSON数据:

const customer = { 
    username: "A8tAz6wdtucMNKvWSgDkx4bquc2", 
    timestamp: { 
        _seconds: 1578762627, 
        _nanoseconds: 828000000 
    }, 
    role: "user" 
};

请注意,timestamp只是具有两个属性的普通对象:_seconds_nanoseconds。这是错误“无法将[object Object]编码为Firestore值”的地方。来自,即数据对象customer包含另一个对象timestamp,Firestore无法解析该对象。为了解决这个问题,我们要做的是确保timestamp不是普通对象,而是admin.firestore.Timestamp的实例。这是您的操作方式:

const seconds = customer.timestamp._seconds;
const nanosecs = customer.timestamp._nanoseconds;

// create a new Timestamp object passing in the required constructor arguments
const properTimestamp = new admin.firestore.Timestamp(seconds, nanosecs);
customer.timestamp = properTimestamp; // update the timestamp reference in your data object
// Now you can do this
test.firestore.makeDocumentSnapshot(customer, '/users/A8tAz6wdtucMNKvWSgDkx4bquc2')

现在,如果您执行console.log(customer);,将会看到timestamp对象是admin.firestore.Timestamp的实例,这是控制台输出:

// OUTPUT
{
    username: 'A8tAz6wdtucMNKvWSgDkx4bquc2',
    timestamp: Timestamp { _seconds: 1578762627, _nanoseconds: 828000000 },
    role: 'user'
}

PS:通过检查Firebase如何尝试解析数据中的值/对象,我得到了答案。这是解析失败并引发异常的地方(在文件../node_modules/firebase-functions-test/lib/providers/firestore.js:165:15中):

if (val instanceof firebase_admin_1.firestore.Timestamp) {
        return {
            timestampValue: val.toDate().toISOString(),
        };
    }