Ошибка при сохранении данных JSON в коллекцию Firestore с использованием облачной функции - PullRequest
0 голосов
/ 21 февраля 2020

Я пытаюсь вставить массив в мою коллекцию Firebase из облачной функции. Мне нужно иметь несколько строк в одном документе, поэтому для каждой строки я вставляю массив. Пожалуйста, проверьте мой прикрепленный скриншот, где вы можете видеть line0, так же, как мне нужно, чтобы Line1, Line2, Line3 .., Line n были в том же документе.

для line0 я передаю массив из кода, как показано ниже, и его работает нормально.

admin.firestore().collection("qbContestWinners").add(
        {
            'cmpientryid': context.params.processId,
            'qbid': '',
            'qbsyncdate': '',
            'qbsyncstatus': 'pending',
            'Line0':
            {
                id: "0",
                description: 'PRIZE AMOUNT',
                amount: 1000,
                accountrefid: contestresultData.qbcontestid,
                accountrefname: contestresultData.qbcontestname,
                contestresultId: context.params.processId,
            },
        })

когда я зацикливаюсь на данных, которые я получаю из другой таблицы, я не могу сгенерировать правильное значение JSON для вставки.

ниже показано, как я зацикливаюсь и создание JSON после получения данных из другой таблицы.

   i = 1;
            admin.firestore().collection("results").where('cid', '==', 'LKRRk2XXXXXXXX')
            .orderBy("rank", "asc").get().then(snapshots =>
                        {
                            snapshots.forEach(doc =>
                                {
                                    const contestresultId = doc.id;
                                    const prizeAmount = doc.data().prizeamt;
                                    const userId = doc.data().userid;
                                    const lineNum = "Line" +  i;
                                    console.log("new line numner is: ", lineNum);
                                    console.log(`lineNum? ${lineNum}`);

                                    const linetxt = "Line" + String(i);
                                    const insertData = "{"+linetxt +
                                                        ":{id:'" + i +
                                                         "', description: 'PRIZE AMOUNT'"+
                                                           ", amount:" + prizeAmount + "," +
                                                           "accountrefid:"+ contestresultData.qbcontestid +","+
                                                           "accountrefname:'" +contestresultData.qbcontestname +"',"+
                                                           "contestresultId:'" + contestresultId +"'," +
                                                       "},}"
                                      const finalInsert = JSON.stringify(insertData);
                                      const finalJSON = JSON.parse(finalInsert);
                                       admin.firestore().collection("qbContestWinners").doc(mainID).set(

                                         finalInsert.toJSON(),

                                    {
                                        merge: true
                                    });

                                i= i+1;
                            });
            });

с использованием этого кода я получаю ошибку finalInsert.to JSON не является функцией enter image description here

Ответы [ 2 ]

2 голосов
/ 21 февраля 2020

На самом деле, поле Line0 является картой, а не массивом, подробнее см. Этот do c.

Итак, если вы хотите создать похожие поля ( Line1, Line2, ...), вам просто нужно передать JavaScript Object методу set() следующим образом:

snapshots.forEach(doc => {
        const contestresultId = doc.id;
        const prizeAmount = doc.data().prizeamt;
        const userId = doc.data().userid;
        const lineNum = "Line" +  i;
        console.log("new line numner is: ", lineNum);
        console.log(`lineNum? ${lineNum}`);

        const lineObj = {
            id: i,
            description: 'PRIZE AMOUNT',
            accountrefid: contestresultData.qbcontestid,   //Not sure if you have defined contestresultData somewhere...
            //...
        }

        const dataObj = {};
        dataObj["Line" + i] = lineObj   // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Property_accessors

        admin.firestore().collection("qbContestWinners").doc(mainID).set(dataObj, {merge: true});

        i= i+1;
});

ОДНАКО , обратите внимание, что вы должны вернуть обещание, которое разрешается после завершения всей асинхронной работы в вашей облачной функции (т. Е. Вызов метода Firestore set()).

Это объясняется в официальной серии Firebase , смотрите, в частности, три видео под названием "Learn JavaScript Promises".

Поскольку вы звоните несколько раз set() метод в forEach l oop, вам нужно использовать Promise.all(), чтобы вернуть Promise, когда все эти параллельные вызовы метода set() завершены.

Следующие действия должны помочь:

let i = 1;
return admin.firestore().collection("results")    // <-- See the return here
.where('cid', '==', 'LKRRk2XXXXXXXX')
.orderBy("rank", "asc").get()
.then(snapshots => {
    const promises = [];

    snapshots.forEach(doc => {
            const contestresultId = doc.id;
            const prizeAmount = doc.data().prizeamt;
            const userId = doc.data().userid;
            const lineNum = "Line" +  i;


            const lineObj = {
                id: i,
                description: 'PRIZE AMOUNT',
                accountrefid: contestresultData.qbcontestid,
                //...
            }

            const dataObj = {};
            dataObj[lineNum] = lineObj;

            promises.push(admin.firestore().collection("qbContestWinners").doc(mainID).set(dataObj, {merge: true}));

        i= i+1;
    });

    return Promise.all(promises)  // <-- See the return here
});

Последнее замечание: , если mainID сохраняет то же значение в snapshots.forEach l oop, вы можете использовать совершенно другой подход, заключающийся в создании объекта JavaScript с несколькими свойствами LineXX и вызове метода set() только один раз. Поскольку вы не передали весь код своей облачной функции, невозможно сказать, следует ли использовать этот подход или нет.

0 голосов
/ 21 февраля 2020

сначала к ошибке

Струнизация и анализ строки. Проблема здесь, кажется, в порядке. Вы должны разобрать «Строку» и привести в соответствие «Объект». Результат также не будет иметь метод до JSON, но вы можете просто упорядочить объект, чтобы получить json.

второе

Почему вы используете строку для создания своего объекта? Ты не должен. Просто используйте объект.

третья вещь

Вы не должны использовать объекты как массивы. Даже в огненной базе.

Просто используйте массивы. Пример:

[Line0Object, Line1Object, ...]

Подсказка: если ваш массив может работать как собственная коллекция. Просто используйте SubCollection. Это может соответствовать вашим потребностям.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...