Reputation: 33
Our Android project uses Firebase Database, and we want to use Firebase Cloud Functions for generating a recommendation for the user. For this, we decided to use npm likely module. Here is my function in index.js:
exports.collaborativeFiltering = functions.database.ref('users/{userID}/checkinlist/{newItem}')
.onWrite(event => {
const userID = event.params.userID;
const newItem = event.params.newItem;
const rootRef = admin.database().ref();
const userPreviouslyVisitedArray = [];
const userRef = rootRef.child('users').child(userID);
const userCheckinListRef = rootRef.child('users').child(userID).child('checkinlist');
var checkinIdList = [];
const foodMatrixRef = rootRef.child('foodUserCheckinMatrix');
var foodUserVenueMatrix = [];
var userIDsArray = [];
var venueIDsArray = [];
var isFirst = true;
var denemeCount = 0;
foodMatrixRef.once('value').then(function(snapshot){
console.log("database read started");
snapshot.forEach(function(child){
if (isFirst){
denemeCount = 0;
var userFoodArray = [];
child.forEach(function(child2){
if(denemeCount < 100){
userFoodArray.push(child2.val());
venueIDsArray.push(child2.key);
denemeCount++;
}
});
foodUserVenueMatrix.push(userFoodArray);
//console.log("user added to matrix with id:", child.key);
userIDsArray.push(child.key);
isFirst = false;
}
else {
denemeCount = 0;
var userFoodArray = [];
child.forEach(function(child2){
if (denemeCount < 100) {
userFoodArray.push(child2.val());
denemeCount++;
}
});
foodUserVenueMatrix.push(userFoodArray);
//console.log("user added to matrix with id:", child.key);
userIDsArray.push(child.key);
}
});
console.log("user ids Array length", userIDsArray.length);
console.log("venue ids Array length", venueIDsArray.length);
console.log("food matrix length", foodUserVenueMatrix.length);
console.log("food matrix's first array length", foodUserVenueMatrix[0].length);
/* var Recommender = require('likely');
//inputmatrix is fooduservenuematrix
//rowlabels array is userids array
//column labels array is venueids array
try{
var Model = Recommender.buildModel(foodUserVenueMatrix, userIDsArray, venueIDsArray);
}
catch(error) {
console.error(error);
}
var recommendations = Model.recommendations(userID);
console.log("recommendation 1: ", recommendations[0]);
console.log("recommendation 2: ", recommendations[1]);
console.log("recommendation 3: ", recommendations[2]);
*/
});
return 0;
})
If I comment out every line after requiring likely, it reads the necessary information from the database and puts it in the foodUserVenueMatrix. I can check this with the console.log statements I put in the code. They are printed in the console.
However, the problem starts when I take the code which uses likely out of comment, it does not print anything on the console, except for the usual function started and function ended info. It doesn't even print the console.log statements it should print before those lines of code is executed. It doesn't seem to be throwing any exceptions, either.
I also tried running likely with a dummy matrix whose values I typed randomly, and it worked fine. So I don't think there's anything wrong with the usage of likely.
What could the problem be here?
Upvotes: 0
Views: 68
Reputation: 317497
For database triggers must return a promise that resolves when all the asynchronous work in the function is complete. once() is async and does not block the function, so it returns immediately before the data is available to the callback. You should be using the promise returned from once() (and not the callback function parameter) to respond when the data is available.
If you don't return a promise that resolves when all the work is complete, Cloud Functions may clean up your function stop all of its work before it's complete.
Upvotes: 1