Облачные функции Firebase генерируют ошибку обещания при записи транзакции Firestore - PullRequest
0 голосов
/ 13 апреля 2020

Когда я пытаюсь провести транзакцию в пожарном депо, появляется ошибка с обещанием. На самом деле, у меня была проблема с этим же кодом раньше, и я был очищен в этой теме Firebase Cloud Functions выдает await как ошибку при записи транзакции в firestore

Ниже приведен код

Это ошибка, выданная

=== Deploying to 'library-1be0e'...

i  deploying functions
Running command: npm --prefix "$RESOURCE_DIR" run lint

> functions@ lint /home/abibv/Downloads/Development/PDL Library/Nec-it-Library-PWA/functions
> eslint .


/home/abibv/Downloads/Development/PDL Library/Nec-it-Library-PWA/functions/index.js
  166:21  error  Each then() should return a value or throw  promise/always-return

✖ 1 problem (1 error, 0 warnings)

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! functions@ lint: `eslint .`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the functions@ lint script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/abibv/.npm/_logs/2020-04-13T02_51_17_897Z-debug.log

Error: functions predeploy error: Command terminated with non-zero exit code1

Вот код

 return admin.firestore().runTransaction(transaction => {
            return transaction.get(memberRef).then(async(doc) => {
                    var transactionRef = admin.firestore().collection('transactions').doc();
                    var transId = '';
                    // write Transaction
                    try {
                        var setData = await transaction.set(transactionRef, transactionData);
                        transId = transactionRef.id;
                    } catch (error) {
                        console.log(error);
                        throw new functions.https.HttpsError(
                            'unknown',
                            'New user cannot be created at the moment due to some unknown reasons. Please try again'
                        )
                    }

                    transaction.set(memberRef, {
                        transactionId: transId
                    }, { merge: true })

                    transaction.update(membeRef, {
                        totalBooks: totalBooks - keys.length
                    });

                    transactionBooks.forEach(transBook => {
                        transaction.update(transBook, {
                            status: false
                        })
                    })


                })
                .catch(error => {
                    console.log(error);
                    return error;
                })
        })
        .then(result => {
            console.log(result);
            return { message: 'Issued' };
        })
        .catch(error => {
            console.log(error);
            return error;
        });

Не могу ли я использовать async / await вместо { then () catch ()} ??? В чем причина этой ошибки? Заранее спасибо.

Вот полный код функции

exports.issueBook = functions.https.onCall(async(data, context) => {
    if (!(context.auth && context.auth.token.admin)) {
        throw new functions.https.HttpsError(
            'unauthenticated',
            'only authenticated Admins can Issue Books'
        );
    }

    memberData = {
        name: data.issueData.memberName,
        no: data.issueData.memberNo,
        role: data.issueData.memberRole,
    }
    transactionData = {
        books: data.issueData.books,
        creation: new Date(),
        member: memberData,
    }

    var keys = Object.keys(transactionData.books);
    var date = new Date();
    transactionData.books["takenDate"] = date;
    date.setDate(date.getDate() + 7);
    var dueDate = date;
    if (transactionData.memberRole === "student") {
        transactionData.books["dueDate"] = dueDate;
    }

    const membeRef = admin.firestore().collection('users').doc(transactionData.member.no);
    var memberDoc = await membeRef.get();
    if (!memberDoc.exists) {
        try {
            await memberRef.set({
                name: data.issueData.memberName,
                no: data.issueData.memberNo,
                email: data.issueData.memberEmail,
                role: data.issueData.memberRole,
                created: data.issueData.created,
                totalBooks: 5,
            })
        } catch (error) {
            console.log(error);
            throw new functions.https.HttpsError(
                'unknown',
                'New user cannot be created at the moment due to some unknown reasons. Please try again'
            );
        }
    }

    var transactionBooks = [];

    try {
        keys.forEach(async(docNo) => {
            book = await admin.firestore().collection('books').where("no", "==", docNo).limit(1);
            transactionBooks.push(book);
        })
    } catch (error) {
        console.log(error);
        throw new functions.https.HttpsError(
            'unknown',
            'Book Data cannot be read at the moment. Please try again'
        );
    }

    return admin.firestore().runTransaction(transaction => {
            return transaction.get(memberRef).then((doc) => {

                if (doc.data().role === 'student' && keys.length > doc.data().totalBooks) {
                    throw new functions.https.HttpsError(
                        'failed-precondition',
                        'Student cannot have more than 5 Books'
                    );
                }

                const transactionRef = admin.firestore().collection('transactions').doc();
                var transId = '';
                // write Transaction
                transaction.set(transactionRef, transactionData);
                transId = transactionRef.id;

                transaction.set(memberRef, {
                    transactionId: transId
                }, { merge: true });

                transaction.update(membeRef, {
                    totalBooks: totalBooks - keys.length
                });

                transactionBooks.forEach(transBook => {
                    transaction.update(transBook, {
                        status: false
                    })
                });
            });
        })
        .then(result => {
            console.log(result);
            return { message: 'Issued' };
        })
        .catch(error => {
            console.log(error);
            return error;
        });
});

1 Ответ

0 голосов
/ 13 апреля 2020

Строка проблемы здесь.

return transaction.get(memberRef).then(async(doc) => {

Вам не нужно устанавливать async. Потому что transaction.set() не возвращает Promise. Поэтому вам не следует использовать await и try catch в следующем коде.

                  try {
                        var setData = await transaction.set(transactionRef, transactionData);
                        transId = transactionRef.id;
                    } catch (error) {
                        console.log(error);
                        throw new functions.https.HttpsError(
                            'unknown',
                            'New user cannot be created at the moment due to some unknown reasons. Please try again'
                        )
                    }

См .:

Пример.

    return admin.firestore().runTransaction(transaction => {
        return transaction.get(memberRef).then((doc) => {
            const transactionRef = admin.firestore().collection('transactions').doc();
            transaction.set(transactionRef, transactionData);

            transaction.set(memberRef, {
                transactionId: transactionRef.id
            }, {merge: true})

            transaction.update(membeRef, {
                totalBooks: totalBooks - keys.length
            });

            // What are transactionBooks?
            transactionBooks.forEach(transBook => {
                transaction.update(transBook, {
                    status: false
                })
            })


        }).catch(error => {
            console.log(error);
            return error;
        })
    })
        .then(result => {
            console.log(result);
            return {message: 'Issued'};
        })
        .catch(error => {
            console.log(error);
            return error;
        });

Обновлено

Сообщение об ошибке: Each then() should return a value or throw promise/always-return.

См .:

Итак, вы должны вернуть значение или выдать следующую асин c функцию.

Пример.

exports.issueBook = functions.https.onCall(async (data, context) => {
    if (!(context.auth && context.auth.token.admin)) {
        throw new functions.https.HttpsError(
            'unauthenticated',
            'only authenticated Admins can Issue Books'
        );
    }
    memberData = {
        name: data.issueData.memberName,
        no: data.issueData.memberNo,
        role: data.issueData.memberRole,
    }
    transactionData = {
        books: data.issueData.books,
        creation: new Date(),
        member: memberData,
    }

    var keys = Object.keys(transactionData.books);
    var date = new Date();
    transactionData.books["takenDate"] = date;
    date.setDate(date.getDate() + 7);
    var dueDate = date;
    if (transactionData.memberRole === "student") {
        transactionData.books["dueDate"] = dueDate;
    }

    const membeRef = admin.firestore().collection('users').doc(transactionData.member.no);
    var memberDoc = await membeRef.get();
    if (!memberDoc.exists) {
        try {
            await memberRef.set({
                name: data.issueData.memberName,
                no: data.issueData.memberNo,
                email: data.issueData.memberEmail,
                role: data.issueData.memberRole,
                created: data.issueData.created,
                totalBooks: 5,
            })
        } catch (error) {
            console.log(error);
            throw new functions.https.HttpsError(
                'unknown',
                'New user cannot be created at the moment due to some unknown reasons. Please try again'
            );
        }
    }

    var transactionBooks = [];

    try {
        // keys.forEach(async(docNo) => {
        //     book = await admin.firestore().collection('books').where("no", "==", docNo).limit(1);
        //     transactionBooks.push(book);
        // })
        transactionBooks = await Promise.all(keys.map((docNo) => {
            return admin.firestore().collection('books').where("no", "==", docNo).limit(1).get();
        }))
    } catch (error) {
        console.log(error);
        throw new functions.https.HttpsError(
            'unknown',
            'Book Data cannot be read at the moment. Please try again'
        );
    }

    return admin.firestore().runTransaction(transaction => {
        return transaction.get(memberRef).then((doc) => {

            if (doc.data().role === 'student' && keys.length > doc.data().totalBooks) {
                throw new functions.https.HttpsError(
                    'failed-precondition',
                    'Student cannot have more than 5 Books'
                );
            }

            const transactionRef = admin.firestore().collection('transactions').doc();
            var transId = '';
            // write Transaction
            transaction.set(transactionRef, transactionData);
            transId = transactionRef.id;

            transaction.set(memberRef, {
                transactionId: transId
            }, {merge: true});

            transaction.update(membeRef, {
                totalBooks: totalBooks - keys.length
            });

            transactionBooks.forEach(transBook => {
                transaction.update(transBook, {
                    status: false
                })
            });

            // Add return
            return null;
        });
    })
        .then(result => {
            console.log(result);
            return {message: 'Issued'};
        })
        .catch(error => {
            console.log(error);
            return error;
        });
});
...