Flutter + Firebase: send last topic message to a user on connect - flutter

I would like to know if this scenario can be implemented with Firebase Cloud Messaging:
My flutter app needs to receive messages with certain updates generated by a server.
Each time data changes, a new message is sent and all connected users that are subscribed to the topic receive it. The messages are not very frequent, lets say 1 every 30 minutes.
However, when a new client connects, that client only must receive the current status of the topic (the last sent message)
Imagine, as an example, a weather app, that receives weather updates every 30 minutes, but when you first open the app, it must be able to request the current weather status without waiting for the next update.
How this feature can be implemented with FCM?
Thanks!

Related

Sync data from REST and Websockets

we are building chat application similar to messenger. There is required behavior:
User log in
User should see last N messages, and he should be able to load older messages
New messages should be appended as well
My solution:
I would like to use websockets for this purpose with combination of REST. My idea was that client application decide by message id which messages need. So REST will be used for initial fetching of messages and fetching older messages.
New messages will received by websockets
Possible issue which I should handle:
Application starts subscribing websocket channel for new messages and send request for old messages without initial message id
There is chance that after calling GET request new message come, and will be stored in DB
Client application started subscribing websocket channel so message will received by websockets.
GET request didn't know about this message and fetch last N messages where this new messages will occured and client application will have duplicate record and have to filtered this messages
Can you give me advice if there is some elegant way how to handle this case? Thank you.
I would resolve your task having in mind the following:
The client application should know only about the topic to which to listen. And not the ID of the message starting from which to listen.
It is up to the server to decide what to return (even time should always be tracked server-side).
The WebSocket is used as a transport for STOMP (simply to not reinvent the wheel). The WebSocket connection could be opened once the client application is loaded and not when it is entering the "listen for messages" state. But topic subscription should be performed when necessary.
You can always send GET request and initiate a STOMP subscription simultaneously (almost simultaneously, well with a delay of 1-2 nano-second). And those always should be processed in different promises. But I would align those in the following way: first, the STOMP subscription is initiated, And a specific message on subscription with the initial timestamp of the start of subscription is delivered; second, REST request to get previous 10-100 messages for the TOPIC prior to a specific timestamp (received from STOMP) is performed.
Getting the last 10 messages (which are prior to subscription moment) could be delivered as by REST as by STOMP approach: you can always react to a subscription event on your server-side, and deliver client-specific messages.
Regarding the problem of multiple identical messages from different "data channels", it is easily resolvable: your client (hope that is not jquery, but rather Angular or React or Vue or anything else) will be storing all the data in a single collection in a controller, and filtering and checking by message-id that only unique entries are stored is easy.
BUT if your system will produce hundreds of thousands of messages per second: I guess HTTP-based protocols are not your choice in this case.

How to force the flutter app to request new data from the server?

I have an app made in flutter that requests data from a rest api. Currently, every time the app starts, it requests new data from the server. It also does that every 5 minutes.
I would like to know if there is any way to tell all apps from the server to request new data.
The purpose of this system is to avoid polling every 5 minutes and have information in the app almost instantly.
One way that occurred to me is to send a push notification indicating that there is new data. But I don't know how to do this. There are examples for sending notifications using firebase, but I am not using that service.
I also thought about web sockets but I think it is very expensive to maintain an open connection between the app and the server.
Any hold will be eternally grateful
I recommend you to use Firebase Cloud Messaging & Firebase Functions:
Firebase Functions could expose an HTTP Event
https://firebase.google.com/docs/functions/http-events
This event can send a push notification to the App and then you could listen to request new data
https://github.com/FirebaseExtended/flutterfire/blob/master/packages/firebase_messaging/example/lib/main.dart

How to store the chat messages in to ionic storage?

I created a chat application using ionic and socket.io-client.
In my app when I select a user to begin chat with, my App loads recent chat data from the server then presents it to the user. If there is no network connection, then user cannot see the previous chat messages. so, I want to store the chat messages in to ionic local storage or there is any other better way to store them.
Please kindly advice me a better way to load my recent chat between two users, instead of fetching from the server each time the user is selected.
You already said it, ionic storage is the way to go: https://ionicframework.com/docs/storage/
For each conversation I would:
1. Send message to server
2. storage.get(conversationID) ....
3. add message and last message send timestamp to conversation
4. storage.set(conversationID) ....
When loading messages:
1. storage.get(conversationID) ....
2. Check if newer messages are available
3. If yes -> fetch
3.1. add messages and last message send timestamp to conversation
4. storage.set(conversationID) ....
Always display the local values only and update those when receiving anything. You can also remember object references when sending messages and mark them as not send if any network exception occurs.

How to get new message detailes via Gmail push notifications?

I have java server application. And I need to monitor a lot of gmail accounts to be able to send push notifications to mobile devices about new Inbox messages.
I need to know sender email and message subject to send push notification.
And I tried Gmail push notifications system (webhooks option)
If I understood everything correctly in order to get needed info for each new message for each user there is a following scenario:
Google sends me email and history id via https request.
I call history API and get new message ids for user
I request message info by message id
That means that I need 2 additional requests for each new message of each user. And it looks quite hard if server needs to handle several new messages each second. And I still don't see other way.
Is there any way to make it shorter? (e.g. to make google send me not only history id but needed new message details or at least make one additional request, but not two)
Thanks!
We tried using Push notifications but the volume of requests generated has meant that we poll on a timed basis instead. It is worth noting that you will get Push notifications for any change to the message such as a label change, a read status change etc. As you say there are many requests.
If you need the notifications real-time I don't see how you can avoid the process that you outline.
If you don't need it real-time then you can poll or at the least check for Push notifications per account on a timed basis and if some have been received retrieve any new messages in a batch rather than a single request.
I was facing the same problem. History API was not giving recent messageId. I solved this problem by hitting THREAD API where i set Q = last 5 min timestamp.
Webhook push notification is helping to notify a new mail has come. After i get all messages last 10 min with THREAD API.

How to handle multiple push notifications with user data arrived at different times?

My app is receiving APNs sent from server to Apple backend. Naturally a user may not open the app once a notification arrives to user's device. In meantime my server may push more notifications. They all contain some user data that is important when a notification is processed. So how to deal with it? iOS won't bundle and give me a batch, will it?
Here are ways how I am going to tackle it, none of which is simple.
Server keeps track of not seen data and upon arriving a new request always sends a batch of all new notifications, reflecting the count as badge count.
Client is opened by taping on notification popup. In this case it has all needed data in didReceiveRemoteNotification.
OR
Client ignores notification popup and opens app (possibly later) by tapping on app icon. In this case didReceiveRemoteNotification is not called and thus app has to fetch all needed data from server.
OR
Server never sends any user data and client always checks for new stuff every time it starts or fetches data in didReceiveRemoteNotification.
Anything else? Something simpler I am missing?
Number 4 is the right approach. There is no guarantee that any of your app code will run when an APN is received, except on iOS7. So when your app starts, it has to check with your servers for any new information that it should display.
It's simplest to code this to alway ask your servers for the latest information to display, rather than rely on the information in the APN. Use the information in the APN only to determine which new information to navigate to, so that the app displays whatever the user tapped on.
This has changed with iOS7, where you can use the remote-notification background mode to be launched whenever a push message arrives. See https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplicationDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UIApplicationDelegate/application:didReceiveRemoteNotification:fetchCompletionHandler: