How to make a difference between messages I sent and others I received when reading messages - mesibo

I use read message API to get all messages for one conversation between two users.
The result is the following (check image). enter image description here
How I am supposed to know what are the messages I have sent and others I received?
The purpose is to display the conversation like in the picture.enter image description here
This is how I read messages sent between two users.
function readConversationWithUser(userId){
return new Promise((resolve) => {
var messageSession = api.readDbSession(userId.toString(), 0, null,
function on_read(count) {
var messages = messageSession.getMessages();
resolve(messages);
});
messageSession.enableReadReceipt(true);
messageSession.read(100);
});
}
userId is my user's unique address.
Thank you very much for your help!
PS: Is there any library to use with angular application or typescript?

Related

How to determine whether it's a SignUp or SignIn in Passwordless Auth from Firebase? [duplicate]

My use case is that I want to ask newly signed up users to enrich basic info like their names.
So I was hoping to do it like:
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
if (some indicator tells me it is newly signed up user)
{redirect to a form to fill in more info}
} else {
// No user is signed in.
}
});
I checked the doc, and could not find anything related to this...
Thanks for the help in advance.
Since version 4.6.0: https://firebase.google.com/support/release-notes/js#4.6.0
You can get if a user is new or existing in 2 ways:
If you are getting back a UserCredential result, check result.additionalUserInfo.isNewUser
Check firebase.auth().currentUser.metadata.creationTime === firebase.auth().currentUser.metadata.lastSignInTime
Previously you had to do that on your own and keep track of the user using Firebase Realtime Database. When a user signs in, you check if a user with the specified uid exists in the database or not. If the user was not found, it is a new user, you can then add the user to the database. If the user is already in the database then this is a returning existing user. Here is an example in iOS.
Handing Firebase + Facebook login process
Example for using result.additionalUserInfo.isNewUser:
firebase.auth().signInWithPopup(provider).then((result) => {
console.log(result.additionalUserInfo.isNewUser);
});
One thing you can do is do things in the callback function of the signup function, the signup function do return a promise. You can do something like this:
firebase.auth().createUserWithEmailAndPassword(email, password)
.then(function(user) {
//I believe the user variable here is the same as firebase.auth().currentUser
//take the user to some form you want them to fill
})
.catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
// ...
});
However, I don't really recommend doing it this way because the client side code can be unreliable. Think about what if a user suddenly disconnect before they can fill the form. Their data will be incomplete in your database. So if you do it this way, do set a flag in your user's profile when they submit the form so that you know who filled detailed information and who didn't.
Another better way to do this is using firebase cloud functions. You can have code like this in your cloud functions. Cloud functions are written in node.js so you don't need to spend time on another language.
exports.someoneSignedUp = functions.auth.user().onCreate(event => {
// you can send them a cloud function to lead them to the detail information form
//or you can send them an welcome email which will also lead them to where you want them to fill detailed information
});
This way is much better because you can safely assume that your cloud functions server will never be down or compromised. For more information about cloud functions you can refer to their doc: https://firebase.google.com/docs/functions/auth-events
You can check the sign-in methods the user has (if any). If there are none, it is a new user.
// Fetch sign in methods (if any)
Auth.auth().fetchSignInMethods(forEmail: userEmail!) { [self] signInMethodsArray, error in
// Check for error and alert user accordingly
if let error = error {
// handle errors
}
// Email accepted.
// Check if new or returning user.
else {
if (signInMethodsArray == nil) {
// New User
}
else {
// Returning User
}
}
}
This is Swift (iOS) code, but the concept is the same across languages.

Firebase Auth, how to know new user signed up, rather than existing user sign in?

My use case is that I want to ask newly signed up users to enrich basic info like their names.
So I was hoping to do it like:
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
if (some indicator tells me it is newly signed up user)
{redirect to a form to fill in more info}
} else {
// No user is signed in.
}
});
I checked the doc, and could not find anything related to this...
Thanks for the help in advance.
Since version 4.6.0: https://firebase.google.com/support/release-notes/js#4.6.0
You can get if a user is new or existing in 2 ways:
If you are getting back a UserCredential result, check result.additionalUserInfo.isNewUser
Check firebase.auth().currentUser.metadata.creationTime === firebase.auth().currentUser.metadata.lastSignInTime
Previously you had to do that on your own and keep track of the user using Firebase Realtime Database. When a user signs in, you check if a user with the specified uid exists in the database or not. If the user was not found, it is a new user, you can then add the user to the database. If the user is already in the database then this is a returning existing user. Here is an example in iOS.
Handing Firebase + Facebook login process
Example for using result.additionalUserInfo.isNewUser:
firebase.auth().signInWithPopup(provider).then((result) => {
console.log(result.additionalUserInfo.isNewUser);
});
One thing you can do is do things in the callback function of the signup function, the signup function do return a promise. You can do something like this:
firebase.auth().createUserWithEmailAndPassword(email, password)
.then(function(user) {
//I believe the user variable here is the same as firebase.auth().currentUser
//take the user to some form you want them to fill
})
.catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
// ...
});
However, I don't really recommend doing it this way because the client side code can be unreliable. Think about what if a user suddenly disconnect before they can fill the form. Their data will be incomplete in your database. So if you do it this way, do set a flag in your user's profile when they submit the form so that you know who filled detailed information and who didn't.
Another better way to do this is using firebase cloud functions. You can have code like this in your cloud functions. Cloud functions are written in node.js so you don't need to spend time on another language.
exports.someoneSignedUp = functions.auth.user().onCreate(event => {
// you can send them a cloud function to lead them to the detail information form
//or you can send them an welcome email which will also lead them to where you want them to fill detailed information
});
This way is much better because you can safely assume that your cloud functions server will never be down or compromised. For more information about cloud functions you can refer to their doc: https://firebase.google.com/docs/functions/auth-events
You can check the sign-in methods the user has (if any). If there are none, it is a new user.
// Fetch sign in methods (if any)
Auth.auth().fetchSignInMethods(forEmail: userEmail!) { [self] signInMethodsArray, error in
// Check for error and alert user accordingly
if let error = error {
// handle errors
}
// Email accepted.
// Check if new or returning user.
else {
if (signInMethodsArray == nil) {
// New User
}
else {
// Returning User
}
}
}
This is Swift (iOS) code, but the concept is the same across languages.

Daily Firebase HTTP Request to trigger FCM Notification

I have FCM up and running in my app and I can send notifications through the Firebase console to all users or a specific user based on the fcmToken stored in a user's profile.
My app allows users to submit daily updates, answers to a set of questions about their health. Whenever a user does this I update the child path /userId/lastDailyUpdate with a date in form yyyyMMdd (ie. 20170805) as an Integer. I do this so that I can hide the questions and submit views if a user has already submitted their input for that specific day.
What I would like to do now, is to use Firebase Cloud Functions in combination with a daily cron job at 8pm to check if a user has submitted their answers. In short, if current date (yyyyMMdd as Int) is larger than date Int stored in /userId/lastDailyUpdate send a notification.
I can send notifications using Cloud Functions, but cannot find a way to loop through all users in my database and checking their lastDailyUpdate values. My code so far:
let functions = require('firebase-functions');
let admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendDailyReminder = functions.https.onRequest((request, response) => {
response.send("Daily Reminder Function");
let userId = "P3fPW62PaxX45Ccvo4OiyOk6fJC2"
// See the "Defining the message payload" section below for details
// on how to define a message payload.
var payload = {
notification: {
title: 'Had a healthy day?',
body: 'Submit you stats before you go to sleep.',
badge: '1',
sound: 'default'
}
};
return admin.database().ref('/users/P3fPW62PaxX45Ccvo4OiyOk6fJC2/fcmToken').once('value').then(allToken => {
if (allToken.val()) {
const token = Object.keys(allToken.val());
return admin.messaging().sendToDevice(token, payload).then(response => {
});
}
});
});
The above code works, but as you can imagine I want to send to more than 1 user :)
The path to lastDailyUpdate value (for user 'P3fPW62PaxX45Ccvo4OiyOk6fJC2' in this example) is:
'/users/P3fPW62PaxX45Ccvo4OiyOk6fJC2/lastDailyUpdate'
I have only been programming for a short while, I know a good amount of JS, but these functions have got me puzzled. Is there anyone who can help me in the right direction?
I am thinking of a HTTP request to trigger a for loop that checks the lastDailyInput value and if smaller than current date trigger then sending of a notification.
Any help with code or tips (possibly on a crash course for Express/Node.js) would be very much appreciated.

How do I make an Angular2 application update instantly on all connected devices as the events are fired?

I need to build a restaurant management mobile application with Angular2 and Ionic2 and a website for the same restaurant with Angular2 that constantly make http connections to store and retrieve data from the database in order to maintain the latest data.
For example, If an order request was fired from a waiter's mobile phone, the new order is posted to the database, which I can accomplish. the chef needs to get the instant notification that a new order has been created. Also, the data needs to be reflected in other employees' phones and also on the website.
All I can come up with is the use of setInterval, but since I've never done anything like this before, I'm not sure if this is the correct way.
component
orders: Order[];
constructor(private orderService: OrderService) {
setInterval(function() {
this.orderService
.getOrders()
.subscribe(
(orders: Order[]) => this.orders = orders,
(error: Response) => console.log(error)
)}, 3000);
}
placeanOrder(order) {
this.orderService.postOrder(order);
}
service
getOrders() Observable<any>{
this.http.get(...).map(...);
}
placeOrder(order) {
this.http.post(...).map(...);
}
When I try something like this, I get the same error logged to the console every second.
Cannot read property 'getOrders' of undefined
Why am I getting the error?
How would I convert the Observable json data retrieved from server into my interface data type, in this case, of type Order?
What is a better approach to this?
Cause wrong usage of callbacks! You have to use the arrow-syntax!
wrong: setInterval(function() {
right: setInterval(() => {
Just describe your function with correct types:
getOrders(): Observable<Order[]> {
Nothing else needed. Property-names needs to be the same (interface/json)!
It's ok to use a timer. "Better" could be a never-closed-connection to the server, so server could SEND you that data and client don't have to POLL.
https://www.websocket.org/
http://socket.io/

Meteor/MongoDB pull data reactively

I have a method that checks for all unread messages belonging to a user. When the app loads, this number appears next to the "Messages" drop down. In Meteor, how would I update this count or variable for when a new message comes in or when the user reads an unread message? Pretty much I needs the method to send down the new count anytime a message status changes without refreshing the app itself.
I'm familiar with the Tracker.autorun functionality but I don't think it'll help with this situation. What's the best practice for approaching this?
Use Publish/Subscribe. It is always reactive. If you do not want to have all unread messages sent to the client straight away and counted there, you create a custom collection that justs count the number of unread messages and publishes that count. Look at the example a bit down in the linked page that starts with
// server: publish the current size of a collection
This is exactly your use case.
I have exactly this setup for new messages. In my header I have:
<li>Messages <span class="counter">{{Messages.count}}</span></li>
And then I have a helper that returns the cursor:
Template.header.helpers({
Messages: function(){ return Messages.find(); }
});
In the old days, before David Weldon set me straight I used to have a helper to return the count, now I just refer to the count directly in the blaze html template.
Now, in this approach I'm subscribing to the Messages collection so that new messages are transmitted to the client and can then be counted locally. This is on the assumption that they are going to be read soon. If you want to avoid this step then you should probably publish a Stats collection or include a stats key in the user object so that just the count itself can be synced via pub-sub.
You can just have a field like read, and update like:
Method for marking one message as read:
markRead: function(messageId){
Messages.update(messageId, {
$set: {
read: true //this needs to be set to false when its inserted
}
})
}
Bulk update method (assuming all messages have receiverId saved):
markAllRead: function(){
Messages.update({receiver: Meteor.userId(), read:false}, {
$set: {
read: true
}
}, {multi: true})
}
You can count read:false ones to retrieve count and you don't have to write anything else
Helper:
count: function(){
//even if your publish/subscribe is correct, the count we want is from messages that are not read and the receiver is current user.
return Messages.find({receiver: Meteor.userId(), read: false }).count();
}
Event:
'click .elementClass': function(){
//both users see the messages and they can both click. We want to update the right message for the right user. Otherwise, the other user can mark the message as read when the receiver is the other user which they shouldn't be able to do. You can do a simple check on the client side, and another check in the method if necessary.
if(this.receiver === Meteor.userId()){
Meteor.call('markAsRead', this._id)
}
}
Let me know if it solves your problem/answers all your questions.

Resources