Wednesday, May 20, 2020

Xamarin.Android - Chat Application Using Firebase - Part One

Ahsan Siddique

 Introduction

Hello everyone!

I am glad that you are here to learn some amazing stuff. In this article, I will show you how to make a chat application with Firebase on Xamarin.Android. This chat application is based on Firebase Auth and Firebase Database by using Xamarin.Firebase plugins.
 
Background

What is Firebase?

Firebase is a mobile and web application development platform developed by Firebase, Inc. in 2011, then acquired by Google in 2014.

Firebase Auth

Firebase Auth is a service that can authenticate users using only client-side code. It supports social login providers Facebook, GitHub, Twitter, and Google. Additionally, it includes a user management system whereby developers can enable user authentication with email and password login stored with Firebase.

Real-time Database

Firebase provides a real-time database and backend as a service. The service provides application developers an API that allows application data to be synchronized across clients and stored on Firebase's cloud. The company provides client libraries that enable integration with Android, iOS, JavaScript, Java, Objective-C, swift and Node.js applications. The database is also accessible through a REST API and bindings for several JavaScript frameworks such as AngularJS, React, Ember.js and Backbone.js. The REST API uses the Server-Sent Events protocol, which is an API for creating HTTP connections for receiving push notifications from a server. Developers using the real-time database can secure their data by using the company's server-side-enforced security rules.

The prerequisites
  • Before using Firebase Real-time Database, make sure that you have connected your Android app to Firebase.
  • Register Application to Firebase
  • Firebase.Xamarin Nuget Package
  • Firebase Database Nuget Package
  • Firebase Auth Nuget Package
  • Android Support Library v7 AppCompat
  • Android Support Design Library
  • Visual Studio 2017

The steps given below are required to be followed in order to create a chat app in Xamarin.Android, using Visual Studio.

Step 1: Create a Project

Open Visual Studio and go to New Project-> Templates-> Visual C#-> Android-> Blank app. Give it a name like ChatAppUsingFirebase.

 

Step 2: Install Android Support Library v7 AppCompat

Go to Solution Explorer-> Project Name-> References. Then, right-click "Manage NuGet Packages" and search for AppCompat. Install the AppCompat package.

 

Step 3: Install Android Support Design Library

Again Solution Explorer-> Project Name-> References. Then, right-click "Manage NuGet Packages" and search for Design Library. Install the Design Library package.

Step 4: Install Xamarin.Firebase.Auth NuGet Package

Similarly, install the Xamarin Firebase Auth package.

 

Step 5: Install Xamarin.FIrebase.Database Nuget Package

Similarly, install the Xamarin Firebase Database package to your application.

 

Step 6: Install Xamarin.Firebase Nuget Package

Similarly, install the Xamarin Firebase package to your application.

 
Step 7: Connect an Android app to FireBase

Go to the firebase site by using this link "https://console.firebase.google.com/u/0/", then go to the console and click on Add Project. Enter Project name and Country and then click on "Create Project".

 
Step 8 
 
Now, click on ‘Add Firebase to your Android App’ and copy the package name of your app followed by a click on Register App. All other fields are optional and can be left blank for now.
 
 
Step 9 
 
In the next step, download the google-services.json file and copy it to the app folder of your Android project. Next, go to the Project Source folder, find the ProjectName.csproj file. Open and edit to add the code given below for Google-services.json config.
 
  
 
After adding the code in ProjectName.csproj file, your project file looks like this.
 
 

Step 10: Email Authentication

By default, the Email/Password Authentication option is disabled. You need to do enable it, therefore, go to Firebase Console, select your project, and click on the "Authentication" tab. Click on the Sign-in method, select Email/Password, and enable it.

  

Step 11: Database access permissions

By default, the read and write access to your database is restricted. So, only authenticated users can read or write data. If you haven’t added an authentication system to your app, it’s the right time to do it. You can also change the Firebase database rules that allow access to the data without requiring authentication. But it is not recommended as it makes your database publicly accessible to anyone.

For this, go to the Firebase console and select your project. Now, click on Database and then select the RULES tab. Replace the following code with Firebase Database Rules and hit the "Publish" button.

 
Step 12 - Add Icon to Drawable

Open Solution Explorer -> Project Name -> Resources-> Drawable. Paste the "Send" icon into the drawable folder with the name "send".

Note
I have divided this article into two parts for the sake of simplicity. In the next part, I will be completing the remaining process of the Xamarin Chat Application.

Friday, May 15, 2020

Xamarin.Android - Build Real Life Applications Using TCP/IP - Part Three

Ahsan Siddique

 Introduction 

Last time, we performed the workstation's sleep functionality on the basis of the client app SLP2 command. In this third and final part of my article series, we will complete the functionality of both of our applications, client, and server. First, we will talk about how the screenshot functionality will perform because the client will only send the TSC1 command and the server will receive this. Then, on the basis of this command, the TakeScreenshot function will perform, which we will write inside the server app.
 
After capturing the screenshot of the current activity of the workstation, we will send it to the client. The size of the picture could be large and we cannot send the large data to the client. Therefore, to achieve this target, we will convert the screenshot data into byte-type packets and then send it to the client. When the client will receive the bytes type packets, it will have to convert them into their original form. We will also perform the shutdown functionality. If a client sends the SHTD3 command to the server application, the server will execute the shutdown function. Finally, if the admin wants to log out from the client application, then we will give this opportunity too to the admin. We will put the "logout" button at the end of the control page. If the admin clicks the "logout" button, the application will navigate to the login page.
Server Application
 
Let's go back to the server application and write the functionality of the screenshot and shutdown workstation. Open the program.cs file and write the following code inside the while loop, that we had implemented in the last episode. In the while loop, we put the try-catch block, and inside, we wrote the condition of If-Else. After if sleep check, you will write the following code.
  1.                     else if (data.ToUpper().Contains("SHTD3"))  
  2.                     {  
  3.                         Console.WriteLine("Pc is going to Shutdown!" + " \n");  
  4.   
  5.                         Shutdown();  
  6.                     }  
  7.                     else if (data.ToUpper().Contains("TSC1"))  
  8.                     {  
  9.                         Console.WriteLine("Take Screenshot!" + " \n");  
  10.   
  11.                         var bitmap = SaveScreenshot();  
  12.                         var stream = new MemoryStream();  
  13.                         bitmap.Save(stream, ImageFormat.Bmp);  
  14.                         sendData(stream.ToArray(), client.GetStream());  
  15.                     }  
Shutdown and TakeScreenshot Functions
 
Add the following namespaces to the server application. Otherwise, Visual Studio will not recognize the graphics keyword of the screenshot function.
  1. using System.Drawing;  
  2. using System.Drawing.Imaging;  
Go back to program.cs and put these functions inside the main class. 
  1. //Workstation Shutdown function  
  2.   
  3. void Shutdown()  
  4.             {  
  5.                 System.Diagnostics.Process.Start("Shutdown""-s -t 10");  
  6.             }  
  7.   
  8. //Save Screenshot function  
  9.   
  10.             Bitmap SaveScreenshot()  
  11.             {  
  12.                 var bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width,  
  13.                                                Screen.PrimaryScreen.Bounds.Height,  
  14.                                                PixelFormat.Format32bppArgb);  
  15.   
  16.                 // Create a graphics object from the bitmap.  
  17.   
  18.                 var gfxScreenshot = Graphics.FromImage(bmpScreenshot);  
  19.   
  20.                 // Take the screenshot from the upper left corner to the right   
  21.   
  22. bottom corner.  
  23.                 gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X,  
  24.                                             Screen.PrimaryScreen.Bounds.Y,  
  25.                                             0,  
  26.                                             0,  
  27.                                             Screen.PrimaryScreen.Bounds.Size,  
  28.                                             CopyPixelOperation.SourceCopy);  
  29.                 return bmpScreenshot;  
  30.             }  
  31.   
  32. //Convert Image to byte type data.  
  33.   
  34.             void sendData(byte[] data, NetworkStream stream)  
  35.             {  
  36.                 int bufferSize = 1024;  
  37.   
  38.                 byte[] dataLength = BitConverter.GetBytes(data.Length);  
  39.   
  40.                 stream.Write(dataLength, 0, 4);  
  41.   
  42.                 int bytesSent = 0;  
  43.                 int bytesLeft = data.Length;  
  44.   
  45.                 while (bytesLeft > 0)  
  46.                 {  
  47.                     int curDataSize = Math.Min(bufferSize, bytesLeft);  
  48.   
  49.                     stream.Write(data, bytesSent, curDataSize);  
  50.   
  51.                     bytesSent += curDataSize;  
  52.                     bytesLeft -= curDataSize;  
  53.                 }  
  54.             }  

We have finished our server application and it's all functionality. Let's start to code our client application.

Client Application
 
Go back to the client application and open the control.axml file. Inside a linear layout, add the following code to create more buttons and picture holders.
 
(Folder Name: Layout , File Name: Control.axml) 
  1.     <Button  
  2.         android:text="Take Screenshot"  
  3.         android:layout_width="match_parent"  
  4.         android:layout_height="wrap_content"  
  5.         android:layout_marginTop="15dp"  
  6.         android:id="@+id/btnTakeScreen" />  
  7.     <Button  
  8.         android:text="Shutdown"  
  9.         android:layout_width="match_parent"  
  10.         android:layout_height="wrap_content"  
  11.         android:id="@+id/btnShutdown" />  
  12.     <ImageView  
  13.         android:id="@+id/imageView"  
  14.         android:layout_width="match_parent"  
  15.         android:layout_height="0dp"  
  16.         android:layout_weight="1" />  
  17.     <Button  
  18.         android:text="Logout"  
  19.         android:layout_width="match_parent"  
  20.         android:layout_height="wrap_content"  
  21.         android:layout_marginBottom="15dp"  
  22.         android:id="@+id/btnLogout" />  
Control Activity
 
Open the control.cs file that we had created in the last episode and replace the following code with appropriate namespaces.
  1.     [Activity]  
  2.     public class Control : Activity  
  3.     {  
  4. //Instances   
  5.         private Button btnTakeScreen, btnSleep, btnShutdown ,btnLogout;  
  6.         private ImageView imageView;  
  7.         NetworkStream stream;  

  8.         protected override void OnCreate(Bundle savedInstanceState)  
  9.         {  
  10.             base.OnCreate(savedInstanceState);  
  11.             var client = Connection.Instance.client;  
  12.             // Create your application here  
  13.             SetContentView(Resource.Layout.Control);  
  14.             btnTakeScreen = FindViewById<Button>(Resource.Id.btnTakeScreen);  
  15.             btnSleep = FindViewById<Button>(Resource.Id.btnSleep);  
  16.             btnShutdown = FindViewById<Button>(Resource.Id.btnShutdown);  
  17.             btnLogout = FindViewById<Button>(Resource.Id.btnLogout);  
  18.             imageView = FindViewById<ImageView>(Resource.Id.imageView);  
  19.   
  20. //Sleep command button  
  21.   
  22.             btnSleep.Click += delegate   
  23.             {  
  24.                 stream = client.GetStream();  
  25.                 String s = "SLP2";  
  26.                 byte[] message = Encoding.ASCII.GetBytes(s);  
  27.                 stream.Write(message, 0, message.Length);  
  28.             };  
  29.   
  30. //Shutdown command button  
  31.   
  32.             btnShutdown.Click += delegate   
  33.             {  
  34.                 stream = client.GetStream();  
  35.                 String s = "SHTD3";  
  36.                 byte[] message = Encoding.ASCII.GetBytes(s);  
  37.                 stream.Write(message, 0, message.Length);  
  38.             };  
  39.   
  40. //Take Screenshot command button  
  41.   
  42.             btnTakeScreen.Click += delegate   
  43.             {  
  44.                 stream = client.GetStream();  
  45.                 String s = "TSC1";  
  46.                 byte[] message = Encoding.ASCII.GetBytes(s);  
  47.                 stream.Write(message, 0, message.Length);  
  48.                 var data = getData(client);  
  49.                 var image = BitmapFactory.DecodeByteArray(data, 0, data.Length);  
  50.                 imageView.SetImageBitmap(image);  
  51.             };  
  52.   
  53. //Logout button  
  54.   
  55.             btnLogout.Click += delegate   
  56.             {  
  57.                 StartActivity(typeof(MainActivity));  
  58.                 client.Close();  
  59.             };  
  60.         }  
  61.   
  62. //Convert byte to Image  
  63.   
  64.         public byte[] getData(TcpClient client)  
  65.         {  
  66.             NetworkStream stream = client.GetStream();  
  67.             byte[] fileSizeBytes = new byte[4];  
  68.             int bytes = stream.Read(fileSizeBytes,0,fileSizeBytes.Length);  
  69.             int dataLength = BitConverter.ToInt32(fileSizeBytes,0);  
  70.   
  71.             int bytesLeft = dataLength;  
  72.             byte[] data = new byte[dataLength];  
  73.   
  74.             int buffersize = 1024;  
  75.             int bytesRead = 0;  
  76.   
  77.             while(bytesLeft > 0)  
  78.             {  
  79.                 int curDataSize = Math.Min(buffersize, bytesLeft);  
  80.                 if (client.Available < curDataSize)  
  81.                     curDataSize = client.Available;//This save me  
  82.   
  83.                 bytes = stream.Read(data, bytesRead, curDataSize);  
  84.                 bytesRead += curDataSize;  
  85.                 bytesLeft -= curDataSize;  
  86.             }  
  87.             return data;  
  88.         }  
  89.     }  

Take Screenshot

Run both projects - server and client. Log in to the client application as admin if you are already registered. Else, register as admin. Put the workstation IP address and port that you can see on the server application output screen into the client application and hit "Connect".
After connecting with the server, now you can perform your task. Click on the "Take Screenshot" button; after a few seconds, you will see the screenshot of the workstation inside the client application.
 
Xamarin.Android - Build Real Life Application Using TCP/IP - Part Three 
 
Shutdown
 
After login and building the connection with the server, hit the "Shutdown" button. You will see a notification that your PC will be shut down in 30 seconds.
 
Xamarin.Android - Build Real Life Application Using TCP/IP - Part Three