我上传了一个云函数来对数据库中的多个位置执行更新操作。
当我上传它时,它工作正常,但突然停止工作,并且在HTTP中,它只是返回了{}
。
我再次查看我的代码,发现现在函数正在返回自身{}
在功能结束之前。
我不知道突然发生了什么事,这破坏了我的整个申请。
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const serviceAccount = require('./myapp.json');
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: 'https://myapp-b2365.firebaseio.com'
});
exports.quarter = functions.https.onRequest((req, res) => {
userType1 = admin.database().ref('users/Type1').once('value');
userType2 = admin.database().ref('users/Type2').once('value');
userType3 = admin.database().ref('users/Type3').once('value');
userType4 = admin.database().ref('users/Type4').once('value');
app_con = admin.database().ref('app_con').once('value');
Promise.all([userType1, userType2, userType3, userType4, app_con]).then(result => {
console.log(0);
result[0].forEach(action => {
action.ref.update({
'AverageRating': (action.val().Rating + action.val().AverageRating )/2,
'Rating': 0
})
});
console.log(1);
result[1].forEach(action => {
action.ref.update({
'AverageRating': (action.val().Rating + action.val().AverageRating )/2,
'Rating': 0
})
});
console.log(2);
result[2].forEach(action => {
action.ref.update({
'Rating': 0
})
});
console.log(3);
result[3].forEach(action => {
action.ref.update({
'Rating': 0
})
});
let q = result[4].val().quarter;
let y = result[4].val().year;
if (q === 4) {
q = 1;
y = y+1;
} else {
q = q+1;
}
console.log(4);
result[4].ref.update({
'quarter': q,
'year' : y
})
return res.send('Done');
}).catch(error => {
return res.status(500).send(error);
})
});
有趣的是,我只看到
的4个console.log()
info: User function triggered, starting execution
info: 0
info: 1
info: 2
info: Execution took 291 ms, user function completed successfully
我不知道发生了什么,怎么可能??
答案 0 :(得分:1)
您的函数具有许多异步代码,并且它不会等待所有操作完成才退出。
您可以通过返回承诺并仅在一切完成后解决它来解决此问题,如下所示:
exports.quarter = functions.https.onRequest((req, res) => {
// return a promise so that the function will wait for it to resolve before exiting
return new Promise((resolve, reject) => {
userType1 = admin.database().ref('users/Type1').once('value');
userType2 = admin.database().ref('users/Type2').once('value');
userType3 = admin.database().ref('users/Type3').once('value');
userType4 = admin.database().ref('users/Type4').once('value');
app_con = admin.database().ref('app_con').once('value');
const promises = [];
Promise.all([userType1, userType2, userType3, userType4, app_con]).then(result => {
console.log(0);
result[0].forEach(action => {
// add each async operation to a promise so that you can wait for them
promises.push(action.ref.update({
'AverageRating': (action.val().Rating + action.val().AverageRating) / 2,
'Rating': 0
}));
});
console.log(1);
result[1].forEach(action => {
promises.push(action.ref.update({
'AverageRating': (action.val().Rating + action.val().AverageRating) / 2,
'Rating': 0
}));
});
console.log(2);
result[2].forEach(action => {
promises.push(action.ref.update({
'Rating': 0
}));
});
console.log(3);
result[3].forEach(action => {
promises.push(action.ref.update({
'Rating': 0
}));
});
let q = result[4].val().quarter;
let y = result[4].val().year;
if (q === 4) {
q = 1;
y = y + 1;
} else {
q = q + 1;
}
console.log(4);
promises.push(result[4].ref.update({
'quarter': q,
'year': y
}));
// wait for all promises created
Promise.all(promises).then(() => {
// only after everything completes you can resolve the promise, which causes the function to exit
resolve(res.send('Done'));
}).catch((error) => {
throw error;
});
}).catch(error => {
reject(res.status(500).send(error));
})
});
});
答案 1 :(得分:0)
里卡多·斯马尼亚(Ricardo Smania)完全正确:您必须使用promises(在您的情况下为private String merchantId;
private String serialNumber;
private String equipmentCode;
private String equipmentCodeDesc;
private String provisionedDeviceType;
private boolean boarded;
private boolean provisioned;
),以便等待所有异步工作完成后再发送回响应。
下面的里卡多代码改编应该起作用:
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
String str = "{\"id\":\"5ZTFCGXQKVZNA\",\"name\":\"xxxx\",\"website\":\"https://xxxx.io\",\"isBillable\":true,\"equipment\":{\"elements\":[{\"merchantId\":\"5ZTFCGXQKVZNA\",\"boarded\":false,\"provisioned\":true,\"serialNumber\":\"C030UQ71040182\",\"equipmentCode\":\"105J\",\"equipmentCodeDesc\":\"Clover Mini\",\"provisionedDeviceType\":\"MAPLECUTTER\"},{\"merchantId\":\"5ZTFCGXQKVZNA\",\"boarded\":false,\"provisioned\":true,\"serialNumber\":\"C050UQ75150054\",\"equipmentCode\":\"1297\",\"equipmentCodeDesc\":\"Clover Station 2018\",\"provisionedDeviceType\":\"GOLDENOAK\"}]}}";
CloverMerchant cv = mapper.readValue(str, CloverMerchant.class);
System.out.println(cv.getId()); //5ZTFCGXQKVZNA
System.out.println(cv.getEquipment().getElements().size()); //2
我建议您观看以下官方视频系列,以了解更多详细信息:https://firebase.google.com/docs/functions/video-series/(尤其是3个视频中的第一个视频,名称为“ Learn JavaScript Promises”)。