Android Question Is using a personal server suitable for the privacy of a messenger app?

jkhazraji

Active Member
Licensed User
Longtime User
I am trying to make a messenger app using b4a to start with and if that succeeded then I would export it to b4i or b4j. I used my rented server on the web to store and retrieve the messages by PHP requests:

-Is this method safe and suitable to use in terms of security and speed as the app will repeatedly make requests to the server? or there is a better solution?

-Second, what is the best method of retrieving data from or saving data to an online database in real time (i.e., once something is stored in the online database then the app will detect it and deal accordingly?
Thanks in advance.
 

nwhitfield

Active Member
Licensed User
Longtime User
In terms of speed, probabaly - but ultimately it depends on message volumes, really.

Security - do you mean it's a dedicated server, or a shared server? A dedicated server is always better, because there's a risk that if it's a shared server, other people may be able to see something in the logs, or access a database table that you've not properly secured. So, make sure you have the permissions for the table set as strictly as possible. Make sure your PHP script is written defensively, so that people can't feed it invalid information to get someone else's data in or out of the database - for example, that might mean that when the app requests a message from the server, you check not just the message id, but also that the recipient matches whatever id the app is using to retrieve the message, and so on.

Secure the web server using certificates (for example, from LetsEncrypt, if you're just experimenting) so that data is encrypted to and from the server.

If you want to go further, either your app or the server side scripts could encrypt the messages before storing them in the database, using recipients' public keys.

In terms of doing this all in real time, that's what my website and the associated apps do. When a user starts our Android app, it signs into the website and receives a session token to identify the user. It also registers with GCM (now, I'd use Firebase, but I've not yet updated that side of things), and when it has an ID for that, it passes it on to the server, and we store the GCM id in a database

When someone, either on the website, or via the app, creates a new message to a member:

1. The message is inserted into the database table
2. We check to see if there's a valid session for that user, and if so, if there's is a GCM id associated with it
3. If the GCM id is found, then we send a notification via GCM/Firebase, which says 'New message on BLUF' with the payload indicating the sender, and a short extract of the message (up to 250 chars), and the message id
4. The notification arrives in the app via GCM, and the app requests the full message from the server
5. The server uses the session token to verify that the message requested is for the user, and if so returns the full message to the app

Most of the time, the GCM notifications will arrive within a second of the message originally being sent. This is plenty fast enough to appear to be a real time chat, though obviously as you get more users, you'll have to scale up your systems accordingly.

In terms of sending, the app posts a message to a script on the server, which includes the destination member id, the session token, and the text of the message
 
Upvote 0

jkhazraji

Active Member
Licensed User
Longtime User
Thanks for your great, up-to-the-point and comprehensive answer.
I quote: "It also registers with GCM (now, I'd use Firebase, but I've not yet updated that side of things), and when it has an ID for that, it passes it on to the server, and we store the GCM id in a database"
How does the Android app register with GCM ? can you give a short code example of registering with GCM(or Firebase)?
 
Upvote 0

udg

Expert
Licensed User
Longtime User
Did you consider the MQTT alternative too? For messages like those exchanged in a chat app is really good.
I tested it successfully with a free service called cloudmqtt then installed an MQTT server on a dedicated server. Running it just for in-house experimenting not for a service open to the public. Anyway, anything works fine.
 
Upvote 0

nwhitfield

Active Member
Licensed User
Longtime User
As I say, you're best off using Firebase, but I don't think there's a massive difference, really. The code is based on an example from the forums, using a service module called PushService, which is documented in this thread

https://www.b4x.com/android/forum/t...ion-gcm-framework-and-tutorial.19226/#content

There are other examples with Firebase too. I've only used Firebase in the b4i context, and there I find that I never seem to get back the device id. That doesn't matter so much there, as Firebase support 'topic' messaging, so rather than sending notifications to specific device IDs, with Firebase, you can have the device subscribe to a topic. So, if a user's member id is 2509 on my site, for instance, all the iOS 'Navigator' clients subscribe to a topic called /topics/bluf_navigator_2509

I'd recommend looking at Firebase rather than GCM if you're starting from scratch.

I'd also recommend planning for diversity; the different apps that work with my site not only identify the user and session, but the app in use when they communicate with the server. The database also allows me to define multiple 'notification channels', so when an app lets the server know it's ready for notifications, we store the type with it.

Then, when a notification needs to sent, we check the channel too; if it's 'android' then I proceed as described via GCM in my previous message, and if it's 'ios-firebase' then we use Firebase as outlined in this message, to reach clients using the newer iOS app. There's also an 'email' channel, for members who opt for instant delivery of messages via the email, instead of on site.

When I finally switch the Android app to Firebase, I'll just create a channel for that, and I'll only have to update the notification sender script on the site, and change a database entry, rather than hack lots of other stuff. The script works over all the registered channels for a particular recipient, so they'll get notifications via whatever way they want them - it would be trivial to drop in an SMS channel, for instance.
 
Upvote 0

nwhitfield

Active Member
Licensed User
Longtime User
MQTT will, to a great extent, avoid recreating the wheel - however if security is a concern, you will be better off running it on a server of your own, rather than buying time on a public one.

Also, of course, it depends exactly what sort of functionality you want.

In the case of bluf.com the majority of our users are web based, so storing everything in a local database makes sense. It also means we can easily add functions based around the database, like the ability to search all your messages for the person who mentioned "stockhausen" whose name you can't remember, or the ability to 'unsend' messages that haven't yet been read, after those drunken late night conversations, or the ability to allow users to flag messages in particular ways (for example, we allow 'archiving' to a per-correspondent history, or flagging as 'favourite' and 'starred'

So, as with many things, think about exactly what you're trying to achieve, before you get stuck into too much coding, and tying yourself to a specific design. A messenger app can mean a lot of different things to a lot of different people. Should a new client (say someone gets a new phone) be able to grab previous conversations, or will they only exist on the phone? Does it need to integrate with other things on a web site? And so on ...
 
Upvote 0

jkhazraji

Active Member
Licensed User
Longtime User
That's great but can't we use a service or timer in our app to watch any new data(message) added to our server database and deal with it instead of going all this long way?!
Pardon me but what is the use of GCM registration?
 
Upvote 0

nwhitfield

Active Member
Licensed User
Longtime User
If you use a service or a timer in your app, your app has to be running all the time, and you're constantly polling for messages, which itself may put quite a load on the server, as your userbase grows - especially if people want messages to be almost instant.

Using Firebase or GCM, your app can be in the background, doing pretty much nothing - not running the battery down, not eating up a data allowance, both of which may matter a lot to your users - but when someone sends a message, Android will wake the app up, pass it the notification, and you can process it almost instantly.

If you used long polling via (say) a PHP script on your server, yes you could get near real time notifications without using GCM/Firebase, but if your app is closed, they'll stop. If you switch between wifi and mobile data, and your IP address changes, the current polling will stop. And you'll be forcing your app to keep running, keeping a data connection open, affecting battery life and performance.

In my view, a timer or long polling can be a suitable solution for a modest number of clients that aren't going to suddenly go away, or change IP addresses - essentially desktop apps, or desktop web browsers. They're a bad solution for mobile.
 
Upvote 0
Top