How to build an Android messenger app with online presence using Kotlin

While building a talk application, it is fundamental to have a web-based presence include. It is fundamental on the grounds that your clients will get a kick out of the chance to know when their companions are on the web, and are bound to answer their messages progressively. In this article, we will fabricate a courier application with online presence utilizing Pusher Channels, Kotlin, and Node.js. Here is a demo of what we will construct: Requirements To track with you really want the accompanying necessities: A Pusher Channel application. You can make one here. Android Studio introduced on your machine. You can really take a look at here for the most recent stable variant. At least variant 3.0 is suggested. Fundamental information on Android improvement and the Android Studio IDE. Fundamental information on Kotlin. Here are the authority docs. Node.js and NPM (Hub Bundle Chief) introduced on your machine. Download here. Mongo DB introduced on your machine. You can introduce it adhering to the guidelines here. Some experience with Android advancement is likewise required. click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here click here Building the backend server Our server will be constructed utilizing Node.js. To begin, make another task registry: $ mkdir backend-server Then, make a new index.js record inside the undertaking registry and glue the accompanying code: // Record: ./index.js var express = require(‘express’); var bodyParser = require(‘body-parser’); const mongoose = require(‘mongoose’); var Pusher = require(‘pusher’); var application = express(); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ expanded: misleading })); var pusher = new Pusher({ appId: ‘PUSHER_APP_ID’, key: ‘PUSHER_APP_KEY’, secret: ‘PUSHER_APP_SECRET’, group: ‘PUSHER_APP_CLUSTER’ }); mongoose.connect(‘mongodb://127.0.0.1/db’); const Blueprint = mongoose.Schema; const userSchema = new Schema({ name: { type: String, required: valid, }, count: {type: Number} }); var Client = mongoose.model(‘User’, userSchema); userSchema.pre(‘save’, function(next) { on the off chance that (this.isNew) { User.count().then(res => { this.count = res;//Addition count next(); }); } else { next(); } }); module.exports = Client; var currentUser; /* ================================= We will add our endpoints here!!! ================================= */ var port = process.env.PORT || 5000; app.listen(port); In the bit above, we instated Pusher, Express, and MongoDB. We are utilizing Moongose to associate with our MongoDB case. Supplant the PUSHER_APP_* keys with the ones on your Pusher dashboard. Presently how about we add our endpoints. The main endpoint we will add will be to log a client in. Glue the code underneath in your index.js record beneath the currentUser statement: // Document: ./index.js // […] app.post(‘/login’, (req,res) => { User.findOne({name: req.body.name}, (blunder, client) => { if (fail) { res.send(“Error associating with data set”); } // Client exists if (client) { currentUser = client; return res.status(200).send(user) } let newuser = new User({name: req.body.name}); newuser.save(function(err) { if (blunder) toss fail; }); currentUser = newuser; res.status(200).send(newuser) }); }) // […] This endpoint gets a username with the solicitation, and either makes another client or returns the information of the current client. How about we add the following endpoint beneath the one above: // Record: ./index.js // […] app.get(‘/clients’, (req,res) => { User.find({}, (fail, clients) => { if (fail) toss blunder; res.send(users); }); }) // […] This subsequent endpoint gets every one of the clients from the information base and brings them back. Since we will utilize a Pusher presence channel, we want an endpoint to verify the client. In a similar record, glue this code beneath the endpoint above: // Document: ./index.js // […] app.post(‘/pusher/auth/presence’, (req, res) => { let socketId = req.body.socket_id; let channel = req.body.channel_name; let presenceData = { user_id: currentUser._id, user_info: {count: currentUser.count, name: currentUser.name} }; let auth = pusher.authenticate(socketId, channel, presenceData); res.send(auth); }); // […] Since we will be utilizing private channels, we want an endpoint for validation. Add the accompanying endpoint underneath the endpoint above: // Document: ./index.js // […] app.post(‘/pusher/auth/private’, (req, res) => { res.send(pusher.authenticate(req.body.socket_id, req.body.channel_name)); }); // […] At last, the last endpoint will be to set off an occasion ‘new-message’ to a channel. Add the endpoint underneath the final remaining one: // Document: ./index.js // […] app.post(‘/send-message’, (req, res) => { let payload = {message: req.body.message, sender_id: req.body.sender_id} pusher.trigger(req.body.channel_name, ‘new-message’, payload); res.send(200); }); // […] In the wake of adding every one of the endpoints, introduce the vital npm bundles by running this order: $ npm introduce express body-parser mongoose pusher Before you run your application, ensure MongoDB is running previously utilizing this order: $ mongod – – dbpath C:\MongoDB\data\db # Windows $ mongod – – dbpath=/way/to/db/catalog # Macintosh or Linux Presently you can run your application utilizing the order beneath: $ hub index.js Your application will be accessible here: http://localhost:5000. Building our Android application Make your Android project. In the wizard, enter your undertaking name — suppose MessengerApp. Then, enter your bundle name. You can utilize a base SDK of 19 then pick an Unfilled Action. On the following page, change the Movement Name to LoginActivity. After this, Android Studio will fabricate your undertaking for you. Since we have the venture, how about we add the expected conditions for our application. Open your application module build.gradle document and add these: // Record ../application/build.gradle conditions { // […] execution ‘com.android.support:design:28+’ execution ‘com.pusher:pusher-java-client:1.6.0’ execution “com.squareup.retrofit2:retrofit:2.4.0” execution “com.squareup.retrofit2:converter-scalars:2.4.0” execution ‘com.squareup.retrofit2:converter-gson:2.3.0’ } Strikingly, we added the conditions for Retrofit and Pusher. Retrofit is a HTTP client library utilized for network calls. We added the plan library reliance too as we need to utilize a few classes from it. Sync your gradle documents to pull in the conditions. Then, how about we set up our application to settle on network decisions. Retrofit requires a connection point to know the endpoints to be gotten to. Make another point of interaction named ApiService and glue this: // Record: ./application/src/principal/java/com/model/messengerapp/ApiService.kt import okhttp3.RequestBody import retrofit2.Call import retrofit2.http.Body import retrofit2.http.GET import retrofit2.http.POST interface ApiService { @POST(“/login”) fun login(@Body body:RequestBody): Call @POST(“/send-message”) fun sendMessage(@Body body:RequestBody): Call @GET(“/clients”) fun getUsers(): Call<List> } Here, we have announced three endpoints. They are for signing in, sending messages, and bringing clients. In a portion of our reactions, we return Call. We should make the UserModel. Make another class called UserModel and glue the accompanying: // Document: ./application/src/primary/java/com/model/messengerapp/UserModel.kt import com.google.gson.annotations.Expose import com.google.gson.annotations.SerializedName information class UserModel(@SerializedName(“_id”) @Expose var id: String, @SerializedName(“name”) @Expose var name: String, @SerializedName(“count”) @Expose var count: Int, var online:Boolean = bogus) Above, we utilized an information class so a few different capabilities expected for model classes, for example, toString and hashCode are added to the class naturally. We are anticipating just the qualities for the id and name from the server. We added the internet based property so we can refresh later on. Then, make another class named RetrofitInstance and glue in the accompanying code: // Record: ./application/src/principal/java/com/model/messengerapp/RetrofitInstance.kt import okhttp3.OkHttpClient import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory import retrofit2.converter.scalars.ScalarsConverterFactory class RetrofitInstance { buddy object { val retrofit: ApiService by languid { val httpClient = OkHttpClient.Builder() val developer = Retrofit.Builder() .baseUrl(“http://10.0.2.2:5000/”) .addConverterFactory(ScalarsConverterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) val retrofit = developer .client(httpClient.build()) .fabricate() retrofit.create(ApiService::class.java) } } } RetrofitInstance contains a class variable called retrofit. It furnishes us with an occurrence for Retrofit that we will reference in more than one class. At long last, to demand for the web access authorization update the AndroidManifest.xml document like so: // Record: ./application/src/primary/ApiService.kt […] Presently we can make demands utilizing Retrofit. The following element we will execute is login. Open the all around made LoginActivity design record activity_login.xml f