firebase 如何将Firestore文档转换为纯json,反之亦然

sczxawaw  于 2023-04-12  发布在  其他
关注(0)|答案(4)|浏览(110)

我试图使用REST API获取firestore文档,它返回以下格式的数据

{"fields":{"list1":{"arrayValue":{"values":[{"stringValue":"item1"},{"stringValue":"item2"}]}}}}

我如何将上面的文档转换为下面这样的普通JavaScript对象,并在进行更新调用之前将其转换回firestore文档

{"list1":["item1","item2"]}

Firestore控制台x1c 0d1x中的数据截图
编辑:更多信息
json sample 1由Firestore API返回,并具有所有数据类型信息
json sample 2是没有类型信息的实际数据。
我的问题是firestore RestApi get调用返回json sample 1格式的响应。我想更新api响应中的一些信息,并将更新后的值发送回firestore db。但由于响应中的所有类型信息,我无法在必要时更新值。所以我试图找到是否有方法将api响应转换为json sample 2。
使用的API URL:https://firestore.googleapis.com/v1/projects/projects/ {project_id}/databases/{database_id}/documents/{document_path}

13z8s7eq

13z8s7eq1#

似乎用REST API唯一的方法就是自己写转换。下面的代码是为我的要求而写的

let jsonToDocument = function (value) {
    if (!isNaN(value)) {
        if (value.toString().indexOf('.') != -1)
            return { 'doubleValue': value };
        else
            return { 'integerValue': value };
    } else if (value === 'true' || value === 'false' || typeof value == 'boolean') {
        return { 'booleanValue': value };
    } else if (Date.parse(value)) {
        return { 'timestampValue': value };
    } else if (typeof value == 'string') {
        return { 'stringValue': value };
    } else if (value && value.constructor === Array) {
        return { 'arrayValue': { values: value.map(v => jsonToDocument(v)) } };
    } else if (typeof value === 'object') {
        let obj = {};
        for (let o in value) {
            obj[o] = jsonToDocument(value[o]);
        }
        return { 'mapValue': { fields: obj } };
    }

}
let documentToJson = function (fields) {
    let result = {};
    for (let f in fields) {
        let key = f, value = fields[f],
            isDocumentType = ['stringValue', 'booleanValue', 'doubleValue',
                'integerValue', 'timestampValue', 'mapValue', 'arrayValue'].find(t => t === key);
        if (isDocumentType) {
            let item = ['stringValue', 'booleanValue', 'doubleValue', 'integerValue', 'timestampValue']
                .find(t => t === key)
            if (item)
                return value;
            else if ('mapValue' == key)
                return documentToJson(value.fields || {});
            else if ('arrayValue' == key) {
                let list = value.values;
                return !!list ? list.map(l => documentToJson(l)) : [];
            }
        } else {
            result[key] = documentToJson(value)
        }
    }
    return result;
}
let documentData = { "list1": { "arrayValue": { "values": [{ "stringValue": "item1" }, { "stringValue": "item2" }] } } }
let jsonData = documentToJson(documentData);
let documentData1 = jsonToDocument(jsonData).mapValue.fields;
console.log(JSON.stringify(documentData));
console.log(JSON.stringify(jsonData));
console.log(JSON.stringify(documentData1));
dsekswqp

dsekswqp2#

我只是想建议对@mahindar的答案做一个小的修改来处理'nullValue',因为Firestore最近允许保存空值。

let jsonToDocument = function (value) {
    if (!value) {
        return { 'nullValue': null };
    } else if (!isNaN(value)) {
        if (value.toString().indexOf('.') != -1)
            return { 'doubleValue': value };
        else
            return { 'integerValue': value };
    } else if (value === 'true' || value === 'false' || typeof value == 'boolean') {
        return { 'booleanValue': value };
    } else if (Date.parse(value)) {
        return { 'timestampValue': value };
    } else if (typeof value == 'string') {
        return { 'stringValue': value };
    } else if (value && value.constructor === Array) {
        return { 'arrayValue': { values: value.map(v => jsonToDocument(v)) } };
    } else if (typeof value === 'object') {
        let obj = {};
        for (let o in value) {
            obj[o] = jsonToDocument(value[o]);
        }
        return { 'mapValue': { fields: obj } };
    }

}
let documentToJson = function (fields) {
    let result = {};
    for (let f in fields) {
        let key = f, value = fields[f],
            isDocumentType = ['stringValue', 'booleanValue', 'doubleValue',
                'integerValue', 'timestampValue', 'mapValue', 'arrayValue', 'nullValue'].find(t => t === key);
        if (isDocumentType) {
            let item = ['stringValue', 'booleanValue', 'doubleValue', 'integerValue', 'timestampValue', 'nullValue']
                .find(t => t === key)
            if (item)
                return value;
            else if ('mapValue' == key)
                return documentToJson(value.fields || {});
            else if ('arrayValue' == key) {
                let list = value.values;
                return !!list ? list.map(l => documentToJson(l)) : [];
            }
        } else {
            result[key] = documentToJson(value)
        }
    }
    return result;
}
let documentData = { "list1": { "arrayValue": { "values": [{ "stringValue": "item1" }, { "stringValue": "item2" }] } }, "another_value": { "nullValue": null } }
let jsonData = documentToJson(documentData);
let documentData1 = jsonToDocument(jsonData).mapValue.fields;
console.log(JSON.stringify(documentData));
console.log(JSON.stringify(jsonData));
console.log(JSON.stringify(documentData1));
z8dt9xmd

z8dt9xmd3#

如何将Firestore文档转换为普通JSON对象:

function toValue(field) {
  return "integerValue" in field
    ? Number(field.integerValue)
    : "doubleValue" in field
    ? Number(field.doubleValue)
    : "arrayValue" in field
    ? field.arrayValue.values.map(toValue)
    : "mapValue" in field
    ? toJSON(field.mapValue)
    : Object.entries(field)[0][1];
}

function toJSON(doc) {
  return Object.fromEntries(
    Object.entries(doc.fields ?? {}).map(([key, field]) => [key, toValue(field)])
  );
}
xnifntxz

xnifntxz4#

要转换此输入:

{"fields":{"list1":{"arrayValue":{"values":[{"stringValue":"item1"},{"stringValue":"item2"}]}}}}

对于此输出:

{"list1":["item1","item2"]}

您可以:

let input = {"fields":{"list1":{"arrayValue":{"values":[{"stringValue":"item1"},{"stringValue":"item2"}]}}}};

let expected = {"list1":["item1","item2"]};

let output = {};
Object.keys(input.fields).forEach((fieldName) => {
  let arrayValue = input.fields[fieldName].arrayValue;
  if (arrayValue) {
    output[fieldName] = arrayValue.values.map((value) => value.stringValue);
  }
});

console.log(output);

相关问题