#javascript #node.js #firebase #firebase-realtime-database #firebase-admin
#javascript #node.js #firebase #firebase-база данных в реальном времени #firebase-администратор
Вопрос:
У меня есть облачная функция, которая запускается при определенной записи в базу данных (onCreate), она работает, как ожидалось, но также выдает ошибку «Функция, возвращенная неопределенной, ожидаемое обещание или значение», хотя я возвращаю обещание. Прикрепляю приведенный ниже фрагмент кода. в нем есть вложенные обещания. есть ли лучший способ обработки вложенных обещаний, я уже проверил много сообщений на наличие вложенных обещаний, но не смог найти правильное решение. Заранее спасибо
exports.calculateAnswer = function(snap, context, dbPath,bucket) {
const answerKey = snap.val();
const incidentId = context.params.incidentId;
const matchId = context.params.match;
var globalIncidentPath = globalIncidentRootPath.replace('${match}', matchId);
globalIncidentPath = globalIncidentPath incidentId '/'
var pdPath = pdRootPath.replace('${match}', matchId);
pdPath = pdPath incidentId
pdPath = pdPath "/" bucket
var incidentsPath = incidentsRootPath.replace('${match}', matchId);
var earningsNodePath = earningsNodeRootPath.replace('${match}', matchId);
let app = admin.app();
var globalData = null;
var globalData = null;
const globalPromise = app.database(dbPath).ref(globalIncidentPath).once('value').then(function(snapshot) {
globalData = snapshot.val();
console.log("globalData ",globalIncidentPath, "data ",globalData);
if(globalData) {
console.log("fetching pddata")
return app.database(dbPath).ref(pdPath).once('value')
}
else{
console.log("No global data found");
return true
}
}).then(function(pdSnashot){
const pdData = pdSnashot.val()
if(pdData) {
var promises = []
pdSnashot.forEach(function(childSnap){
console.log('key ',childSnap.key)
console.log('users count ',childSnap.numChildren())
childSnap.forEach(function(usersSnap){
const userId = usersSnap.key
const incidentProcessed = incidentsPath userId '/processed/' incidentId
if (childSnap.key === answerKey) {
const earningUserIdEPath = earningsNodePath userId
//const earningEPath = earningUserIdEPath '/e/'
let gocashValue = globalData['v'];
const earningFetchPromise = app.database(dbPath).ref(earningUserIdEPath).once('value').then(function(snapshot1){
let snapDict = snapshot1.val();
var newGoCash = gocashValue
var newPDGoCash = gocashValue
if (snapDict){
let currentGoCash =snapDict['e'];
let currentPDCash = snapDict['pd']
if(currentGoCash) {
newGoCash = currentGoCash gocashValue;
}
if(currentPDCash) {
newPDGoCash = currentPDCash gocashValue;
}
}
const obj = Object()
obj["e"] = newGoCash
obj["pd"] = newPDGoCash
const earningPromise = app.database(dbPath).ref(earningUserIdEPath).update(obj)
const tempGlobal = globalData
tempGlobal["skip"] = false;
const processedPromise = app.database(dbPath).ref(incidentProcessed).set(tempGlobal)
return Promise.all([earningPromise,processedPromise])
});
promises.push(earningFetchPromise)
}
else{
const tempGlobal = globalData
tempGlobal["skip"] = true;
const processIncidentPromise = app.database(dbPath).ref(incidentProcessed).set(tempGlobal);
promises.push(processIncidentPromise)
}
})
})
return Promise.all(promises).then(value => {
console.log("Pd promises completed",value);
return true
})
}
else{
console.log("No Pd Data Found");
return true
}
})
.catch(function(error){
console.log('error in promise resolve',error)
})
console.log('global promise',globalPromise)
return Promise.all([globalPromise])
})
Комментарии:
1. Пожалуйста, отредактируйте вопрос, чтобы показать всю функцию, а не только часть ее кода. Мне трудно понять, чего пытается достичь ваш код.
2. Вы уверены, что это связано с облачными функциями, как предполагает тема? Я нигде здесь не вижу определения облачной функции.
3. да, это облачная функция, также добавлена начальная строка кода
Ответ №1:
Я бы изменил ваш код следующим образом. Смотрите комментарии в коде.
var globalData = null;
const globalPromise = app
.database(dbPath)
.ref(globalIncidentPath)
.once('value')
.then(function(snapshot) {
globalData = snapshot.val();
console.log('globalData ', globalIncidentPath, 'data ', globalData);
if (globalData) {
console.log('fetching pddata');
return app
.database(dbPath)
.ref(pdPath)
.once('value');
} else {
console.log('No global data found');
// return true; Better to throw an error here
throw new Error('No global data found');
}
})
//The following 3 lines don't bring anything
//Moreover they are most probably the reason of your error as you don't return anything in this then()
//.then(function(pdSnashot){
// console.log("");
//})
.catch(function(error) {
console.log('error in promise resolve', error);
return true;
//Note that if you don't need the console.log you may ommit the entire catch since the platform will handle the error itself.
});
console.log('global promise', globalPromise);
//return Promise.all([globalPromise]); // There is no reason to use Promise.all() here since there is only one promise chain returned in globalPromise
return globalPromise;
Комментарии:
1. Какую ошибку вы получаете в журнале облачной функции? Кроме того, можете ли вы предоставить общий доступ ко всему коду вашей облачной функции, а не только к определению
globalPromise
?2. функция работает должным образом, но, тем не менее, в ней говорится: «Функция вернула неопределенное, ожидаемое обещание или значение».