使用Cloud Functions在Firestore数据库上通过外部API存储数据

问题描述 投票:0回答:1

我有一个在Firebase上运行的Vue.js应用,作为数据库,我使用Firestore。该应用程序必须从另一个应用程序(app2)导入数据(客户端),但是app2仅通过通过POST发送XML代码到地址来导出。要从app2接收POST,我的应用程序使用了Firebase Cloud Functions。

const xml2js = require("xml2js");
const functions = require("firebase-functions");
const cors = require("cors");
const express = require("express");
const app = express(); 
const admin = require("firebase-admin");

const db = admin.initializeApp().firestore();

function parseXml(xml) {
    return new Promise((resolve, reject) => {
        xml2js.parseString(xml, { explicitArray: false }, (err, result) => {
            if (err) {
                reject(err);
            } else {
                resolve(result);
            }
        });
    });
}

app.use(cors({ origen: true }));
    app.post("/", async (request, response) => {
    let xml = request.body.XMLRecords.toString();
    const clientes = db.collection("clientes");
    xml = xml.replace(/&(?!(?:apos|quot|[gl]t|amp);|#)/g, "&").trim();
    xml = " " + xml;

    console.log("Prep XML:");
    console.log(xml);

    let parsXml = await parseXml(xml);
    console.log("parsXML");
    console.log(parsXml);

    Array.from(parsXml.Records.Clientes.Cliente).forEach(async cli => {
        if (cli !== null) {
            delete cli.$;
            const docRef = clientes.doc(cli.CliCodigo);
            console.log("cli " + cli.CliCodigo);
            console.log(cli);
            const writeResult = await docRef.set(cli);
            console.log("Cliente " + cli.CliCodigo + " salvo");
        }
    });

    response.send("Received.");
});

exports.apiClientes = functions.https.onRequest((request, response) => {
    if (!request.path) {
        request.url = `/${request.url}`; // prepend '/' to keep query params if any
    }
    return app(request, response);
});

该应用程序确实收到了请求并能够处理该请求,但是当我尝试与Firestore数据库通信时,该函数将停止发送console.log()语句,并且不会将数据保存到数据库中。我在做什么错?

firebase vue.js google-cloud-firestore google-cloud-functions xml2js
1个回答
0
投票

这很可能是因为在Array.from(parsXml.Records.Clientes.Cliente).forEach()循环中您正在执行几个异步set()操作,但是您正在返回响应(response.send("Received.");在完成这些异步操作之前

通过执行response.send("Received.");,您正在向运行Cloud Function的实例表明它可以终止它,但是在大多数情况下,对Firestore的异步写入未完成。

您需要正确处理set()方法调用返回的Promise,如下所示(未测试):

//....
const promises = [];
Array.from(parsXml.Records.Clientes.Cliente).forEach(cli => {
    if (cli !== null) {
        delete cli.$;
        const docRef = clientes.doc(cli.CliCodigo);
        console.log("cli " + cli.CliCodigo);
        console.log(cli);`

        promises.push(docRef.set(cli));

        console.log("Cliente " + cli.CliCodigo + " salvo");
    }
});

await Promise.all(promises)
response.send("Received.");
//....
© www.soinside.com 2019 - 2024. All rights reserved.