当我试图在firestore上执行事务时,它会抛出一个promise错误。事实上,我以前在这个代码上有问题,在这个线程中被清除了Firebase Cloud函数在firestore Transaction写入时抛出等待
以下是代码
这是抛出错误的
=== 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;
});
});
问题行在这里。
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'
)
}
参见:
- https://firebase.google.com/docs/reference/js/firebase.firestore.Transaction#set
- https://developers.google.com/web/fundamentals/primers/async-functions#async_return_values
Ex。
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
。
参见:
- https://github.com/xjamundx/eslint-plugin-promise/blob/master/docs/rules/always-return.md
- https://pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html
- 每个then((都应该返回一个值或抛出Firebase云函数
因此,您应该返回一个值或抛出以下异步函数。
Ex。
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;
});
});