Reputation: 10839
I have a Firebase Cloud Function that works (it writes to my database as Admin, and also checks for an existing entry with an email string ID). My issue is that it doesn't return the data back to the client app properly.
When I trace the value of result
it is {data: null}
I would also like to throw an error if the email exists, but it complains about an unhandled promise (see the comments in the code below).
So there are two questions here. The first being the most pressing.
exports.saveData = functions.https.onCall( (data, context) => {
// check if the email exists
admin.database().ref('competition_entries/' + data.compId + '/' + data.emailStringId).once('value').then(function(snapshot) {
if (snapshot.val() == null){
console.log("Writing data to "+data.compId+" : "+data.emailStringId);
let current_datetime = new Date()
let formatted_time = current_datetime.getHours() + ":" + current_datetime.getMinutes() + ":" + current_datetime.getSeconds();
let formatted_date = current_datetime.getDate() + "/" + (current_datetime.getMonth() + 1) + "/" + current_datetime.getFullYear();
let timestamp_string = formatted_time+" "+formatted_date;
console.log(formatted_date)
admin.database().ref('competition_entries/' + data.compId + '/' + data.emailStringId).set({
name: data.name,
email: data.email,
phone: data.phone,
selectedItem: data.selectedItem,
submitted_date: timestamp_string
})
.then(() => {
console.log("success");
return {
"error": "none",
"message": "success"
};
}).catch(function(error) {
throw error;
});
}else{
// email address exists as a data entry so tell the user that they have already submitted
let code = "already-exists";
let message = "Email address already exists";
let details = "A user with the same email address has already entered the competition.";
console.log(message+"/"+details);
/*
TODO: throwing an HttpsError directly here was causing an unresolved promise error. This would be the better way to tell the client that the user has already submitted their data.
*/
// throw error;
//throw new functions.https.HttpsError(code, message, details);
// this resolves the promise error but is a hack
return {
error: new functions.https.HttpsError(code, message, details),
message: message
}
}
}).catch(function(error) {
throw error;
});
});
Upvotes: 1
Views: 558
Reputation: 10497
I think the problem is you are not returning enough. Functions needs every function to return something to execute succesfully.
Commonly is return true
or return Promise
So it should be something like this:
//check if email exist
return admin.databse...
//If there is no user create it
return.admin...
The code does write the database but since it was no return that happened asynchronously, and the code would keep executing from top to bottom making the function to response jibberish to the client.
You should
if (!snapshot)
shortcircuiting is better because snapshot could be undefined causing an exception when checkinf if snapshot data is nullUpvotes: 3