How to know if app user is offline android app? - java

Currently i am developing a cab booking app.
Now i am working on driver app.
Now my task is, i want to make him offline and online when ever internet get disconnected orconnected .
In my database i have a column is_online which value goes to 1 when he online and 0 when he is offline.
well now i know how to make him online but how to make him offline? if internet got disconnected ! how can i update value in db . it remain 1
never goes to 0;
Current i am using Broadcast Receiver that notify me when internet get disconnected or connected.
<?PHP
require_once 'include/DB_Settings_Functions.php';
$db = new DB_Functions();
// json response array
$response = array("error" => FALSE);
if(isset($_POST['driver_id'])&&isset($_POST['status']))
{
$driver_id= $_POST['driver_id'];
$status= $_POST['status'];
$user = $db->makeOnline($driver_id,$status);
}
?>
I heard that it can be solved by using mqtt any working example ? can anyone help me? i am using local host wamp server.
Edit:
In simple words i want to send value in server before connection goes down any idea how it can be done using mqtt ?

You can fire a request on every minutes from mobile app and stored it's date and time into data base. if user is online that means last access time will update every minutes in database and if user is offline then it's time last access time will not update in data base so you just need to fire a sql query for get offline user that have last access time is grater then 2 minus.

MQTT has a function called the Last Will and Testament (LWT), this is a messages that is published by the broker when the client connection times out.
This means that the client can publish a retained message to a unique topic when it comes online (e.g. publish 1 to /status). It can then set up a LWT to publish 0 to the same topic if the connection drops. It should also manually publish 0 before manually closing the connection as LWT only fires if the connection drop unexpectantly.
You can adjust the time out value to suit your needs.

Related

Is there a way to delete push notification data message sent by FCM?

In my application, I am offering video and voice calls between users. I'm using Firebase Realtime database and FCM as well to do so.
Here is the data that my notification is delivering:
data: {
channel_id: channel_id,
user_id: user_id
}
In my FirebaseMessagingService class, I retrieve the data and open the Video/Call activity like so:
if(remoteMessage.getData().size > 0) {
Intent intent = new Intent(this, VideoCallActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.putExtra("channel_id", remoteMessage.getData().get("channel_id"));
intent.putExtra("user_id", remoteMessage.getData().get("user_id"));
getApplicationContext().startActivity(intent);
}
Everything is working perfectly even when the application is in background. However, I'm facing this issue:
If an user didn't have internet connection when he was called, when he connects to internet his phone will automatically start the VideoCallActivity even if the call has been aborted (by the caller) and the notification removed from Firebase real time database.
So, please is there a way to cancel sent notifications, or know the delivery status of those notifications, or another way around to do so? That will allow me to add the list of missed calls for users.
Thanks!
In a scenario like this, I know of two options:
Send another FCM message when the call is cancelled
Only use FCM to send a tickle
Send another FCM message when the call is cancelled
One of the properties you can give an FCM message is an collapse_key. When you send a message with a collapse_key, that message replaces any previous message with the same collapse_key value.
You can use this to send a "nope, forget about it" message, when the user cancels the call.
Only use FCM to send a tickle
Alternatively you can have the FCM message just be a so-called tickle: an almost empty message, that just tells the app to wake up and go check its queue of incoming messages in the database.
That way: if the call is still in the database, the app can pick it up. But if there is no call in the database, it can just do nothing.
You'll want to do this type of database interaction in a service, so that it can run when the app is backgrounded.
Giving an expiration time is feasible as suggested in the documentation
Check Here
Setting the lifespan of a message
On Android and Web/JavaScript, you can specify the maximum lifespan of a message. The value must be a duration from 0 to 2,419,200 seconds (28 days), and it corresponds to the maximum period of time for which FCM stores and attempts to deliver the message. Requests that don't contain this field default to the maximum period of four weeks.
Here are some possible uses for this feature:
Video chat incoming calls
Expiring invitation events
Calendar events

How to send push notifications to users that don't enter application more then 2 days?

I haven't my own server and client doesn't want a server. Can i do it with direbase notifications? And how i will calculate how amny days spent from last user session?
--------------------------------NEW ANSWER------------------------------------
You should be able to do this using the Firebase Console. When creating a Cloud Message you can select in the "Target" section "Last App Engagement" and select that you want the message to go to everyone that hasn't engaged with the app for say 1 day.
After that you set in Scheduling that you want it to be a recurring campaign and you set it to happen "Daily" at say 12pm and set that you want each user to get this only once. Now you have a campaign that every day at 12pm checks who wasn't in the App for 1d and sends him the campaign, but only sends it once to not spam the same guy every single day.
--------------------------------OLD ANSWER -----------------------------------
You could create for example a DailyJob within your app and that DailyJob could either on it's own check how many days since last session was active and create a local notification or you could use that DailyJob to send to say Firebase a custom attribute "days_since_last_login" and setup different campaigns for 2 days offline, 7 days offline, 31 days offline and so on in Firebase.
To easily create a DailyJob you can use Evernote Android Job library.
You can use firebase to make push notification.
In this case, you don't have any server to make push notification and track the last user session, I think you can follow this:
Use local notification (not push notification) to notify user.
Store user session to Shared Preferences.
Create a background service to trigger local notification base on the last session stored.
But you should have a clear view of notification on Android to understand how it works first.
This is simple: don't use Firebase or the internet at all.
This is what you want to do: every time the user logs into your app, Create an Alarm for 48 hours (2 days) from when onResume and cancel any previous alarms. Or cancel previous alarms during onResume and create a new one in onPause.
Then, setup the alarm receiver to send a local notification. AlarmManager with Notification Android
Every time the user opens your app, it pushes the local notification back. When they go 2 days without using it, they will get a notification at around the same time that they used it previously.
"Can I do it with firebase notifications?"
Yes, you can with cloud function code.
Just trigger an event after a new notification added to the database.
My below code trigger an event after a new notification added to DB and looks for a post older than 24hrs. You can use it and change it for 48hrs
The code work below:
Trigger event after data is added to DB.
Check the database for old notifications older than 24hrs.
Retrieve them and delete (by changing their value to null);
//DELETE OLD NOTIFICATION LESS THAN 24HRS /////////////////
exports.deleteOldItems = functions.database.ref('/notification/{user_id}/{notification_id}').onWrite((change) => {
const ref = change.after.ref.parent; // reference to the parent
const yesterday = Date.now() - 86400000;
const oldItemsQuery = ref.orderByChild('time').endAt(yesterday);
return oldItemsQuery.once('value').then((snapshot) => {
// create a map with all children that need to be removed
const updates = {};
snapshot.forEach(child => {
updates[child.key] = null;
});
return ref.update(updates);
// execute all updates in one go and return the result to end the function
});
});
////////////////////DELETE FUNCTION ENDED HERE//////////////////////
The most important part is how to calculate for 48hrs (which is 2 days)
PS: this is still 24hrs. I will update the answer when finding a way to convert for 48hrs.
const yesterday = Date.now() - 86400000;
EDIT:172800000 is for 2 days ago (24hrs)
Now, you subtract the current date from 2 days ago and compare it with the notification date.
const yesterday = Date.now() - 172800000;

Gmail watch user inbox, history.getMessagesAdded is not returning the new message

Requirement is to sync mails from Gmail for an user into our CRM. The system in place is based on Google Pub/Sub which watches inbox of the user for any change and fires the notification to our HTTPs endpoint. More on this at Gmail cloud pub/sub.
Based on the above procedure we git history of changes. And then i am interested in only new messages, so history.getMessagesAdded is preferred as per this guide. Issue we are facing now is the first mail of a thread is not captured under messagesAdded all the subsequent messages are passing through our system.
Note: For the first mail, we do get push from Google. But when we try to get Messages added it turns out empty. Is there anything special needs to be done for the first mail of the thread or am i missing out something.
I was experiencing a very similar problem, and my mistake was that I was using the historyId from the push notification, the solution was to store the last known historyId on my database, so, every time I get a notification, I get the history from the id I have stored, not the one from the notification.
In my case, the historyId from the notification doesn't even make part of the history, maybe because of my watch restrictions: labelIds=['INBOX']
This is the google pub/sub notification:
{
message:
{
data: {"emailAddress": "user#example.com", "historyId": "9876543210"},
message_id: "1234567890",
}
subscription: "projects/myproject/subscriptions/mysubscription"
}
I was using the message.data.historyId, wich was causing the confusion!
The message.data, comes as a base64 encoded string, in this example I just decoded it!
Step by step for watching new e-mails on the inbox:
Do all the configuration in the google pub/sub.
Start watching the user with the filters you want (docs.: https://developers.google.com/gmail/api/v1/reference/users/watch)
Store the historyId obtained in the step 2
When receive the notification, get all the events (history) using the stored id as the startHistoryId parameter (docs: https://developers.google.com/gmail/api/v1/reference/users/history/list)
In the history list obtained on the step 4, look for the new messages: history.getMessagesAdded().
Update the last known history id in your database, so you don't need to deal with the whole history every time!
I hope it helps.

how to operate an app running on two tablets from on tablet in android

I am working on app running on two tablets, which have two type of logins. Customer and Shopkeeper, it will run on two tabs at same time. I am getting tabs device id and saving it. because it can't be run on any other tablet without registered tablets.The issue is that after login when I go on main screen, when i enter number from any tablets, the next screen must be changed on both tablets. I am not getting the idea how to operate two tabs from any one of them.Can you help me to get this idea. any help will be appreciated.
I have 2 separate options here :
A. Use CouchDB.
Couch DB has this functionality to sync data between client and server.
Steps :
Tablet1 enter a value
Value saved in tablet1 CouchDB. (You can use something like couchbase-android)
Data synced from client COUCHDB to Server CouchDB ( you can use Cloudant here )
Data synced from Server CouchDB to client CouchDB in the Tablet1
Tablet2 use a listener to listen to record change in the database
Tablet2 change its state based on the record change.
B. Use Notification Server
Tablet1 enter a value
Tablet1 send message to Notification Server, indicating the changes
Notification Server send notification to Tablet2
Tablet2 use Notification Listener to listen to all notification
Tablet2 change it state based on data contained in the notification message.

how to trigger a gcm to send a push notification to android device(using java server)

I am very new to java server side development, i have followed this link [http://javapapers.com/android/google-cloud-messaging-gcm-for-android-and-push-notifications/][1] and successfully implemented GCM with my android device, the problem is dont know how to trigger the GCM server while the content is updated in my db,i need to notify each and every update of my db to the user, am i need to watch the db using timer task something like that or is there any default solution to keep track of db ?
My Server side code :
regId = "my registration id";
String userMessage = request.getParameter("message");
Sender sender = new Sender(GOOGLE_SERVER_KEY);
Message message = new Message.Builder().timeToLive(30)
.delayWhileIdle(true).addData(MESSAGE_KEY, userMessage).build();
result = sender.send(message, regId, 1);
have tried with many solution but till now not getting exact solution, Suggestion, ideas or related links are most welcome
Thanks in advance
Without knowing the specific functionality of your server and app, I can only offer a general solution.
Each process in your server that performs DB updates that have to be pushed to some Android devices via GCM can write the messages and the registration IDs to some kind of queue.
Then you can have another process (or processes) that would consume the queue of GCM messages, and send them to Google. These processes can handle failures (retry sending the messages in case of temporary failures), and update your database of registration IDs if they receive responses with canonical registration IDs or errors such as InvalidRegistration or NotRegistered.

Categories

Resources