Reputation: 21
I'm using DialogFlow for a project, and one part is to register users to a database, which works like it should but I'm checking if the UID already exist in the database, and if it does the user should be alerted, but this does not work. The console.log()
message passes to firebase with the correct information, but it doesn't give any response to DialogFlow, in this case message
will be the response.
Here is my registerUser code:
function registerUser(agent) {
let added = false;
let message = "Not used";
ref.child(uid).once("value", function(snapshot) {
if (snapshot.val() === null) {
ref.child(uid).set({
FIRST_NAME: firstName,
LAST_NAME: lastName
});
added = true;
}
}).then(doc => {
if (added === true) {
message = "Great! You are now added to the database";
console.log("User_added_success");
}
else {
message = "User aldready exists!";
console.log("User_added_fail");
}
});
agent.add(message);
}
The output is "Not used"
as response and the console.log() is "user_added_success"
Upvotes: 1
Views: 548
Reputation: 50701
You have a couple of issues related to how you are using Promises. Promises are used by the Firebase database and Firebase Cloud Functions to handle asynchronous operations in node.js. In modern node.js, Promises are largely preferred over callbacks.
The first issue is that you seem to be mixing callbacks and Promises when you handle the response from the call to Firebase. Since once()
can return a Promise, you don't need to use the callback, but can put it as part of a .then()
block. This might look something like this:
.once("value").then( snapshot => {
if (snapshot.val() === null) {
ref.child(uid).set({
FIRST_NAME: firstName,
LAST_NAME: lastName
});
added = true;
}
return snapshot;
})
The second issue is that anything that is set through a Promise fulfillment has to be read in a later part of the Promise chain. So just like you set added
in the first then()
function and read it in the second one, if you set the message
in the second one, you need to handle it either in that then()
clause or in a later then()
clause. Since there is no other async operation going on, you can just do this after the if/else clause. Perhaps something like this:
if (added === true) {
message = "Great! You are now added to the database";
console.log("User_added_success");
}
else {
message = "User aldready exists!";
console.log("User_added_fail");
}
agent.add( message );
There is one final issue involving Promises, however. If you are using async calls (and thus Promises), you must also return a Promise from your Intent Handler so the Dialogflow library knows to wait for the results before it sends a message back to the user. It isn't clear if this is the handler itself, but if so, the easiest way to deal with this is to return the results of the Promise chain. Since the Firebase database call returns a Promise, this part can be as simple as
return ref.child(uid)
(followed by the .once()
and .then()
methods discussed above).
Upvotes: 1