Firebase Cloud Functions - return undefined - firebase

This is the code that I am using to fetch the senderName and messageText from my database. In my logs, I am getting an error saying "Function returned undefined, expected Promise or value". I am using this function to send notifications to the recevier of the message. The notification is being sent appropriately.
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendPushNotification = functions.database.ref('/messages/{messageId}').onWrite(event => {
var db = admin.database();
var messageText;
var senderName;
var receiverId;
var senderId;
var messageId = event.params.messageId;
var messageTextRef = db.ref('/messages/' + messageId + '/text');
var senderIdRef = db.ref('/messages/' + messageId + '/fromId');
var receiverIdRef = db.ref('/messages/' + messageId + '/toId');
messageTextRef.once("value", function(data) {
messageText = data.val();
senderIdRef.once("value", function(data) {
senderId = data.val();
receiverIdRef.once("value", function(data) {
receiverId = data.val();
var senderNameRef = db.ref('/users/' + senderId + '/name');
senderNameRef.once("value", function(data) {
senderName = data.val();
console.log(senderName);
console.log(messageText);
const payload = {
notification : {
title: String(senderName),
body: String(messageText),
badge: "1",
sound: 'default',
}
};
return admin.database().ref('fcmToken').once('value').then(allToken => {
if (allToken.val()) {
const token = Object.keys(allToken.val());
return admin.messaging().sendToTopic(receiverId, payload).then(response => {
});
};
}, function (errorObject) {
console.log("The read failed: " + errorObject.code);
});
}, function (errorObject) {
console.log("The read failed: " + errorObject.code);
});
}, function (errorObject) {
console.log("The read failed: " + errorObject.code);
});
}, function (errorObject) {
console.log("The read failed: " + errorObject.code);
});
});
});

You have a monster function there. If you return the outermost Promise when you are getting all the database values that should fix the issue, and also ensure that your function is not stopped before all computation is complete. In your case this is on line ~25:
...
return messageTextRef.once("value", function(data) {
...

Related

Firestore query: getting data and storing it into an variable . How to use that variable in cloud functions?

To get a data from the firestore I queried a document and get that data into variable. Now, I need to use that variable in other part of the code.
when I am using that variable it does not get any data . How to resolve these error.
var d1;
var getdata = respond.get()
.then(doc =>{
if(!doc.exists){
console.log('No such document');
}else{
console.log('Document data:', doc.data());
d1 = doc.data();// In d1 I am not getting the data of that document
}
}).catch(err => {
console.log('Error getting documnet', err);
});
Here in for loop, I am using the d1 variable. But it is not executing these for loop
for(var k in d1){
var p = d1[k].PhoneNumber;
let rph = respond.where(receiverph ,"==", p)
.set({
Status : status
});
let payload = {
notification : {
title: "Message",
body: msg,
sound:"default",
}
};
console.log(payload);
return admin.messaging().sendToDevice(token,payload).then((response) =>{
console.log(token);
console.log("Successfully sen notification");
}).catch(function(error){
console.warn("Error sending notification",error);
});
}
});
In d1 the data is
{ Invite2: { PhoneNumber: 917893659558, Amount: 33 },
Invite1: { PhoneNumber: 917799266509, Amount: 33 },
Invite3: { Amount: 33, PhoneNumber: 918639146409 }
}
Use Promisse.all
let promise = [];
let all = [];
for(var k in d1){
var p = d1[k].PhoneNumber;
let rph = respond.where(receiverph ,"==", p)
.set({ Status : status });
let payload = {
notification : {
title: "Message",
body: msg,
sound:"default",
}
};
console.log(payload);
return admin.messaging().sendToDevice(token,payload).then((response) =>{
console.log(token);
console.log("Successfully sen notification");
}).catch(function(error){
console.warn("Error sending notification",error);
});
}
promise.push(rhp);
});
Promise.all(promise).then((data)=>{
data.forEach(query => {
query.forEach(res=>{
all.push(res.data());
})
})
When you get a document with .get, the document has to be fetched from the database. Therefore this operation is asynchronous and you must wait until the document is received before you can iterate on its data. In short, it should look something like the following:
some_doc_ref.get().then(doc => {
if (doc.exists) {
var d1 = doc.data();
for(var k in d1) {
//...
}
}
});
Hope that helps.

upload image with firestore and vue.js [Cannot read property 'id' of undefined]

I'm using element.io to upload images to firebase with vue.js, it's fine, it works. The problem is when I want to update a field of a model, I get this error.
Uncaught (in promise) TypeError: Cannot read property 'id' of
undefined
methods () {
upload(file, fileList) {
this.photo = file.file
if (this.photo) {
let storageRef = firebase.storage().ref('profiles/avatar/'+Date.now()+'/'+this.photo.name);
let uploadTask = storageRef.put(this.photo)
uploadTask.on('state_changed', function(snapshot){
var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
console.log('Upload is ' + progress + '% done');
}, function(error) {
}, function() {
var downloadURL = uploadTask.snapshot.downloadURL
firebase.database().ref('/profiles/' + this.$store.getters.profile.id ).update({ avatar: downloadURL })
})
}
}
}
An error appears in this line, when using the variables that are in my data, I get the same error
function() {
var downloadURL = uploadTask.snapshot.downloadURL
firebase.database().ref('/profiles/' + this.$store.getters.profile.id )
.update({ avatar: downloadURL }) })

How to pass variable key value in dynamodb

Am trying to get the items from DynamoDB table based on the current date. Using the date value in string format when am trying to run the below piece of code, its error out saying:
{
"errorMessage": "ERROR: Dynamo failed: TypeError: Cannot read property 'datatype' of undefined"
}
Below is the piece of code:
exports.handler = function(event, context) {
console.log("Request received:\n", JSON.stringify(event));
console.log("Context received:\n", JSON.stringify(context));
var doc = require('dynamodb-doc');
var dynamodb = new doc.DynamoDB();
var params = {
Key: {
"abc" : datetime1
},
TableName: 'myTable',
ProjectionExpression: 'message'
};
var Message = callback();
var datetiem = new Date().toISOString().split('T')[0];
console.log('date is ', datetiem); // prints 2018-01-09
var datetime1 = JSON.stringify(datetiem);
console.log(datetime1); //prints "2018-01-09"
function callback (message) {
dynamodb.getItem(params, function (err, data) {
if (err) {
context.fail('ERROR: Dynamo failed: ' + err);
} else {
console.log('Dynamo Success: ' + JSON.stringify(data, null, ' '));
console.log('data', data)
let Message = data['Item'].message;
console.log('test',Message);
}
});
}
};
It runs fine if I pass the value directly i.e. "abc" : "2018-01-09"
Can someone please advice?
I'm not sure your datetime1 variable is defined when you use it in parameters. Try this:
exports.handler = function(event, context) {
console.log("Request received:\n", JSON.stringify(event));
console.log("Context received:\n", JSON.stringify(context));
var doc = require('dynamodb-doc');
var dynamodb = new doc.DynamoDB();
var Message = callback();
var datetiem = new Date().toISOString().split('T')[0];
console.log('date is ', datetiem); // prints 2018-01-09
var datetime1 = JSON.stringify(datetiem);
console.log(datetime1); //prints "2018-01-09"
var params = {
Key: {
"abc" : datetime1
},
TableName: 'myTable',
ProjectionExpression: 'message'
};
function callback (message) {
dynamodb.getItem(params, function (err, data) {
if (err) {
context.fail('ERROR: Dynamo failed: ' + err);
} else {
console.log('Dynamo Success: ' + JSON.stringify(data, null, ' '));
console.log('data', data)
let Message = data['Item'].message;
console.log('test',Message);
}
});
}
};

Firebase infinite loop insert my item on child_added/set

I got an infinite loop inserting an item to my Firebase, so when I click on my post form, it inserts my item until I kill the process. Can you help me how to solve it?
PS : I'm using VueJS
var usersRef = new Firebase('https://xxxxxxxxxxxxxxxxxx.firebaseio.com/userslist/');
var vm = new Vue({
el: '#list1',
data: function () {
return{
// Initialisation du tableau de users
users: [],
sortKey: 'id',
reverse: 1,
nextKey: null
};
},
ready: function () {
// this works
//this.sortKey = 'name';
},
methods: {
updateUsers: function () {
},
removeUser: function (item) {
usersRef.child(item.id).remove();
},
addItem: function (e) {
e.preventDefault();
// get form data as Json
var jsonData = ConvertFormToJSON('form_add');
//console.log(jsonData);//test ok
//get the last item id and save it to next key
usersRef.limitToLast(1).on('child_added', function (snapshot) {
var lastKey = parseInt(snapshot.key());
this.nextKey = lastKey + 1;
console.log('nextKey ' + nextKey);//test ok
//
// save data to firebase
usersRef.child(this.nextKey).set(jsonData, function (snap) {
//console.log('add success');//test
//Notification par Jquery
var itemAdded = snap.val();
$.notify(itemAdded.firstname + " " + itemAdded.name + " à été ajouté", "success", {position: "top right"});
this.pendingKey = 0;
});
});
},
// Tri des colonnes
sortBy: function (_sortKey) {
this.reverse = (this.reverse == -1) ? 1 : -1;
this.sortKey = _sortKey;
console.log("SortKey " + this.sortKey);
}
}
});
usersRef.on('child_added', function (snapshot) {
var item = snapshot.val();
item.id = snapshot.key();
console.log('id ' + item.id);
vm.users.push(item);
}, function (errorObject) {
console.log("The read failed: " + errorObject.code);
});
thanks for your help
OK I've found a solution :
//get the last item id and save it to next key
var _nextKey = this.nextKey;
usersRef.limitToLast(1).on('child_added', function (snapshot) {
var lastKey = parseInt(snapshot.key());
_nextKey = lastKey + 1;
});
this.nextKey = _nextKey;
console.log('nextKey ' + this.nextKey);//test ok
// save data to firebase
usersRef.child(this.nextKey).set(jsonData, function (snap) {
//console.log('add success');//test
//Notification par Jquery
var itemAdded = snap.val();
$.notify(itemAdded.firstname + " " + itemAdded.name + " à été ajouté", "success", {position: "top right"});
});
May it help someone!

Can't wait without a fiber

I'm using the node-imap meteor package to retrieve an email, then use that email to find a guest in a Guests collection. I get the "can't wait without a fiber error" when I include the Guest.findOne code. Here's the code
function openInbox(cb) {
imap.openBox('INBOX', true, cb);
}
imap.once('ready', function() {
openInbox(function(err, box) {
if (err) throw err;
var f = imap.seq.fetch(box.messages.total + ':*', { bodies: ['HEADER.FIELDS (FROM SUBJECT DATE)','TEXT'] });
f.on('message', function(msg, seqno) {
console.log('Message #%d', seqno);
var prefix = '(#' + seqno + ') ';
msg.on('body', function(stream, info) {
if (info.which === 'TEXT')
console.log(prefix + 'Body [%s] found, %d total bytes', (info.which), info.size);
var buffer = '', count = 0;
stream.on('data', function(chunk) {
count += chunk.length;
buffer += chunk.toString('utf8');
if (info.which === 'TEXT')
console.log(prefix + 'Body [%s] (%d/%d)', (info.which), count, info.size);
});
stream.once('end', function() {
if (info.which !== 'TEXT') {
console.log(prefix + 'Parsed header: ');
var header = Imap.parseHeader(buffer);
var from = header.from;
email = from[0].slice(from[0].indexOf('<')+1, from[0].indexOf('>'));
fetched = true;
}
else
console.log(prefix + 'Body [%s] Finished', (info.which));
});
});
msg.once('attributes', function(attrs) {
console.log(prefix + 'Attributes: %s', (attrs, false, 8));
});
msg.once('end', function() {
console.log(prefix + 'Finished');
});
});
f.once('error', function(err) {
console.log('Fetch error: ' + err);
});
f.once('end', function() {
console.log('Done fetching all messages!');
imap.end();
if(fetched){
var guest = Guests.findOne({email: email}, {reactive: false}); // <-- this code causes the error
if(guest){
console.log(guest)
}
}
});
});
});
imap.once('error', function(err) {
console.log(err);
});
imap.once('end', function() {
console.log('Connection ended');
});
imap.connect();
So I tried to do a Meteor.bindEnvironment based on Future.wait() can't wait without a fiber (while waiting on another future in Meteor.method)
function openInbox(cb) {
imap.openBox('INBOX', true, Meteor.bindEnvironment(cb));
}
And get the error message "Cannot read property '_meteor_dynamics' of undefined". So there is no Fiber to bind to? I am still fairly new to Meteor so don't really know where to go from here. An explanation on what is going on and a solution would be great. Any help is appreciated.

Resources