unread count in meteor chat application for each room - meteor

i am working on a chat app which have various channels/rooms, want to display the unread messages for each room/channel, iam able to display the unread messages count on the active room of all the participants but not on all the rooms. The helper function is not executed although the new messages are there in the inactive rooms, not sure where is the problem, appreciate for your pointers? thanks
'unReadCount':function(){
var currentuserid=Meteor.userId();
//updateChannelView
console.log("channelid and userid"+this._id + " " + currentuserid);
var res=channelViewLog.findOne({channelId:this._id,userId:currentuserid})
if(res){
var varlastviewed=new Date(res.lastViwed);
//console.log("last viewed timestamp"+varlastviewed + " " + this._id + " " + new Date());
var res1=Messages.find({channel:this._id,createdAt: {$gte:varlastviewed},user:{ $ne: currentuserid}}).count();
return res1;
}
}
Meteor.publish('PubChannelViewLog', function () {
var currentuserid=this.userId;
return channelViewLog.find({userId:currentuserid});
});

Related

Trying To Include Email Address (or User's Name) In Notification Email

I have a Page Fragment that allows users to create an entry. When they click the send button it runs the following:
newSOEmailMessage(widget);
widget.datasource.createItem();
app.closeDialog();
This activates a Client Script that sends an email to the user which includes the values from the widget fields:
function newSOEmailMessage(sendButton) {
var pageWidgets = sendButton.root.descendants;
var currentuser = Session.getActiveUser().getEmail();
var htmlbody = currentuser + 'has created new system order for: <h1><span style="color:#2196F3">' + pageWidgets.ShowName.value + ' - ' + pageWidgets.UsersPosition.value + '</h1>' +
'<p>R2 Order #: <b>' + pageWidgets.R2OrderNumber.value + '</b>' +
'<p>Delivery Date: <b>' + pageWidgets.DeliveryDate.value.toDateString() + '</b>' +
'<p>Start of Billing: <b>' + pageWidgets.SOB.value.toDateString() + '</b>' +
'<p>Sales Person: <b>' + pageWidgets.SalesPerson.value + '</b>' +
'<p> </p>' +
'<p>Company: <b>' + pageWidgets.Company.value + '</b>' +
'<p> </p>' +
'<p>Notes: <b>' + pageWidgets.Notes.value + '</b>';
google.script.run
.withSuccessHandler(function() {
})
.withFailureHandler(function(err) {
console.error(JSON.stringify(err));
})
.sendEmailCreate(
'user#email.com',
'New order for: ' + pageWidgets.ShowName.value + ' - ' + pageWidgets.UsersPosition.value,
htmlbody);
}
All of this works fine except the "currentuser" option (after var htmlbody =). With the code above I get the following error:
Session is not defined
at newSOEmailMessage (Notifications_ClientScripts:7:45)
at SystemOrders_Add.SubmitButton.onClick:1:1
I would like "currentuser" to equal the email address (or preferably the user's actual name).
ex: "John Doe has created a new system order for..."
What am I missing?
Thank you!
Note: I already have a Directory Model setup to show user's names in a comments section for a different Model. That Model is running the following (I'm assuming I could add that to my SystemOrders model?)
// onCreate
var email = Session.getActiveUser().getEmail();
var directoryQuery = app.models.Directory.newQuery();
directoryQuery.filters.PrimaryEmail._equals = email;
var reporter = directoryQuery.run()[0];
Looks like you are mixing server and client side APIs
// It is server side API
var email = Session.getActiveUser().getEmail();
// It is client side API
var email = app.user.email;
If you want to utilize user Full Name from the directory, then you need to load it advance, for instance in app startup script:
// App startup script
// CurrentUser - assuming that it is Directory model's datasource
// configured to load record for current user.
loader.suspendLoad();
app.datasources.CurrentUser.load({
success: function() {
loader.resumeLoad();
},
failure: function(error) {
// TODO: Handle error
}
});
So, you can refer to this datasource item later in your code:
var fullName = app.datasources.CurrentUser.item.FullName;
Also, I would recommend send emails only when record is actually created:
// Sends async request to server to create record
widget.datasource.createItem(function() {
// Record was successfully created
newSOEmailMessage(widget);
});

Querying another easy table for push notification message

I have two easy tables configured in my Azure App backend:
Services with Id and ServiceName properties
ServiceDetails with Id, ServiceID and ServiceDetailDate properties
Whenever a new ServiceDetails entry is inserted, I want to send a message to my users via Push Notifications containing information about ServiceDetailDate and ServiceName.
So my question is how can I query another table to obtain information from it? In this case the ServiceID (from ServiceDetails table) is known, so I want to get the ServiceName from Services. Which code should I add to extract the ServiceName from the serviceInfo object (in the payload message) to my script to fulfill this request?
Actually I'm not sure about the query and serviceInfo instructions, so if I'm wrong with the code, don't hesitate to point me in the right direction.
var azureMobileApps = require('azure-mobile-apps'),
promises = require('azure-mobile-apps/src/utilities/promises'),
logger = require('azure-mobile-apps/src/logger'),
queries = require('azure-mobile-apps/src/query');
var table = azureMobileApps.table();
table.insert(function (context) {
var query = queries.create('Services');
var serviceInfo = query.where({'Id': context.item.ServiceID});
var payload = '{"messageParam": "Your service -service name- has been added on ' + context.item.ServiceDetailDate + '" }';
return context.execute()
.then(function (results) {
if (context.push) {
context.push.send(null, payload, function (error) {
if (error) {
logger.error('Error while sending push notification: ', error);
} else {
logger.info('Push notification sent successfully!');
}
});
}
return results;
})
.catch(function (error) {
logger.error('Error while running context.execute: ', error);
});
});
module.exports = table;
Thanks for your help.
You can use the following code to query another easy table in ServiceDetails.js.
table.insert(function (context) {
return context.tables('Services')
.where({ Id: context.item.ServiceID })
.select('ServiceName')
.read()
.then(function (data) {
var message = 'Your service ' + data[0].ServiceName + ' has been added on ' + context.item.ServiceDetailDate;
var payload = '{"messageParam": "' + message + '"}';
return context.execute().then(function (results) {
//..
});
});
});

Cloud Functions for Firebase - what is wrong with my code?

The following code executed when something is written at a certain location in the database.
What I expect from this code : If the number of coins are => 500 to subtract only once 500 coins from the current coins value and to add one ticket to the existing ticket value.
What I am getting in reality: The code recursively subtracts 500 coins until the coin value is lower than 500; It adds more tickets then it should.
Please , can somebody modify my code to work as expected ?
I do not know what I am doing wrong
exports.TransformCoinsIntoTickets1 = functions.database.ref('/AddTickets/{userid}').onWrite(event => {
var user = event.params.userid;
/// first get coins to see if we can lower coin value
var usercoinRef1 = admin.database().ref('coins').child(user);
usercoinRef1.on("value", function(snapshot) {
var numberofcoins = snapshot.val();
console.log("We are in snapshot of coins -> He has coins = " + numberofcoins);
if (numberofcoins >= 500 )
return usercoinRef1.set(numberofcoins-500).then(() => {
var ticketRef1 = admin.database().ref('tickets').child(user);
ticketRef1.on("value", function(snap123) {
var numberoftickets = snap123.val();
return ticketRef1.set(numberoftickets+1).then(() => {
console.log('Tickets Write succeeded!');
});
}, function (error) {
console.log("Error Tickets: " + error.code);
});
console.log('Coins Write succeeded!');
});
}, function (error) {
console.log("Error Coins: " + error.code);
});
//then we write the new coin value if we need to
});
I just realized that instead of
on
i should use
once
So, replacing
.on("value",
with
.once("value",
resolved the problem.

Calling Meteor Method from within Particle Photon Stream of Promises produces error: Error("Meteor code must always run within a Fiber. "

I'm connecting to Particle.io event stream and trying to call a Meteor Method with the event name and event data from the stream as arguments.
var Particle = Meteor.npmRequire('particle-api-js');
var particle = new Particle();
var particleLogin = particle.login({
username: Meteor.settings.particle_username,
password: Meteor.settings.particle_password
});
particleLogin.then(
function(data) {
var token = data.body.access_token;
console.log(token);
var eventStream = particle.getEventStream({
deviceId: Meteor.settings.PhotonName,
auth: token
});
eventStream.then(function(stream) {
stream.on('event', function(data) {
console.log(data.name + ": " + data.data);
Meteor.call('newStreamData', data.name, data.data); // Produces aforementioned error
});
});
}
)
I've tried including the call from inside of a Meteor.bindEnvironment block and nothing happens.
stream.on('event', Meteor.bindEnvironment(function(data) {
console.log(data.name + ": " + data.data); // Never gets called
Meteor.call('newStreamData', data.name, data.data); // Never gets called
}));

Firebase Displaying Other Users' username except yours Using Presence

Hi I'm new to firebase and was trying out the presence example on firebase everything is working normal. My issue is how do I display the username of others ONLY because everything I cant seem to find the solution for this because
I tried googling for an answer but none of the results are what I'm looking for.
I'm new to Firebase and non-mysql database so I dont know how to do a WHERE Statement on firebase
here is my code:
<body>
<div id="presenceDiv" class="l-demo-container example-base">
</div>
<script>
var name = "<?php echo $uname;?>";
var currentStatus = "★ online";
// Get a reference to the presence data in Firebase.
var userListRef = new Firebase("https://<URL>.firebaseio.com/");
// Generate a reference to a new location for my user with push.
var myUserRef = userListRef.push();
// Get a reference to my own presence status.
var connectedRef = new Firebase("https://<URL>.firebaseio.com//.info/connected");
connectedRef.on("value", function(isOnline) {
if (isOnline.val()) {
// If we lose our internet connection, we want ourselves removed from the list.
myUserRef.onDisconnect().remove();
// Set our initial online status.
setUserStatus("★ online");
}
else {
// We need to catch anytime we are marked as offline and then set the correct status. We
// could be marked as offline 1) on page load or 2) when we lose our internet connection
// temporarily.
setUserStatus(currentStatus);
}
});
// A helper function to let us set our own state.
function setUserStatus(status) {
// Set our status in the list of online users.
currentStatus = status;
myUserRef.set({ name: name, status: status });
}
function getMessageId(snapshot) {
return snapshot.name().replace(/[^a-z0-9\-\_]/gi,'');
}
// Update our GUI to show someone"s online status.
userListRef.on("child_added", function(snapshot) {
var user = snapshot.val();
$("<div/>")
.attr("id", getMessageId(snapshot))
.text(user.name + " is currently " + user.status)
.appendTo("#presenceDiv");
});
// Update our GUI to remove the status of a user who has left.
userListRef.on("child_removed", function(snapshot) {
$("#presenceDiv").children("#" + getMessageId(snapshot))
.remove();
});
// Update our GUI to change a user"s status.
userListRef.on("child_changed", function(snapshot) {
var user = snapshot.val();
$("#presenceDiv").children("#" + getMessageId(snapshot))
.text(user.name + " is currently " + user.status);
});
// Use idle/away/back events created by idle.js to update our status information.
document.onIdle = function () {
setUserStatus("☆ idle");
}
document.onAway = function () {
setUserStatus("☄ away");
}
document.onBack = function (isIdle, isAway) {
setUserStatus("★ online");
}
setIdleTimeout(5000);
setAwayTimeout(10000);
</script>
</body>
</html>
This script keeps on loading my 1st dummy username along the other dummy users that i tried logging on with. The same goes for the other dummy accounts the browser loads their username along with the others.. Whats causing this and how do I solve it? Please help
I'd simply identify and exclude the current user in you on(child_ handlers.
So for example:
// Update our GUI to show someone"s online status.
userListRef.on("child_added", function(snapshot) {
var user = snapshot.val();
if (user.name != name) {
$("<div/>")
.attr("id", getMessageId(snapshot))
.text(user.name + " is currently " + user.status)
.appendTo("#presenceDiv");
}
});

Resources