Introduction
In this article, I will show you how to create a MongoDB database and how to work with it using Xamarin.Android. MongoDB is a document database with the scalability and flexibility that you want with querying and indexing of the data.
Collection in MongoDB
A collection is a group of MongoDB documents. It is equivalent to an RDBMS table. A collection exists within a single database. The collection does not enforce a schema. Documents within a collection can have different fields. Typically, all documents in a collection are of similar or related purpose.
Document in MongoDB
A document is a set of key-value pairs. Documents have a dynamic schema. Dynamic schema means that the document in the same collection does not need to have the same set of fields or structure, and common fields in a collection's document may hold different types of data.
Relationship of RDBMS with MongoDB
RDBMS | MongoDB |
Database | Database |
Table | Collection |
Tuple/Row | Document |
Column | Field |
Table Join | Embedded Document |
Primary Key | Primary Key(Default Key _id provided by MongoDB itself) |
About MLAB
MLab is a fully managed cloud database service that hosts MongoDB database. MLab is based on the cloud providers like Amazon, Google, and Microsoft Azure, and has partnered with Platform-as-a-Service provider.
Create a Mongo Database
Step 1
Go to this URL -
https://mlab.com
Step 2
Click on
"GET STARTED INSTANTLY with 500 MB FREE" and create a new database.
Step 3
Next, select a cloud provider. All the three are free for users. Just select the Plan Type as SANDBOX.
Step 4
Choose the desired Azure region and hit "Continue".
Step 5
Next, put the database name and hit OK.
Step 6
Next, add a new collection.
Step 7
Add a new Document inside the collection.
Step 8
Now, you need to have an API key that will be consumed in the mobile app. Access of these RESTful APIs is disabled by default. Go to User Profile and enable the Generate API key.
Xamarin Android Application
Step 1
Open Visual Studio and go to New Project-> Templates-> Visual C#-> Android-> Blank app. Give it a name, like MongoDB.
Step 2
Next, go to Solution Explorer-> Project Name and right-click. Select Add -> New Item-> Class. Give it a name, like Common.cs and write the following code with appropriate namespaces.
(Class Name: Common)
Common class code
- using System.Text;
- using System.Linq;
- using System;
- using CloudNoSQL.Class;
- namespace CloudNoSQL.Helper {
- class Common {
- private static String DB_NAME = "xamarindb";
- private static String COLLECTION_NAME = "user";
- private static String API_KEY = "ow6xCr4R6mh9Ac-WnOEYe31Uv-4-j5nh";
- public static string getAddressSingle(User user) {
- String baseUrl = $ "https://api.mlab.com/api/1/databases/{DB_NAME}/collections/{COLLECTION_NAME}";
- StringBuilder strBuilder = new StringBuilder(baseUrl);
- strBuilder.Append("/" + user._id.oid + "?apiKey=" + API_KEY);
- return strBuilder.ToString();
- }
- public static string GetAddressAPI() {
- String baseUrl = $ "https://api.mlab.com/api/1/databases/{DB_NAME}/collections/{COLLECTION_NAME}";
- StringBuilder strBuilder = new StringBuilder(baseUrl);
- strBuilder.Append("?apiKey=" + API_KEY);
- return strBuilder.ToString();
- }
- }
- }
Step 3
Similarly, create another class named as HttpDataHandler.cs and write the following code with appropriate namespaces.
(File Name: HttpDataHandler)
- using System;
- using System.Text;
- using Java.Net;
- using Java.IO;
- using System.IO;
- namespace CloudNoSQL.Class {
- public class HttpDataHandler {
- static String stream = null;
- public HttpDataHandler() {}
- public String GetHTTPData(String urlString) {
- try {
- URL url = new URL(urlString);
- HttpURLConnection urlConnection = (HttpURLConnection) url.OpenConnection();
- if (urlConnection.ResponseCode == HttpStatus.Ok)
- {
- BufferedReader r = new BufferedReader(new InputStreamReader(urlConnection.InputStream));
- StringBuilder sb = new StringBuilder();
- String line;
- while ((line = r.ReadLine()) != null) sb.Append(line);
- stream = sb.ToString();
- urlConnection.Disconnect();
- }
- } catch (Exception ex) {
- System.Console.WriteLine("{0} Exception caught.", ex);
- }
- return stream;
- }
- public void PostHTTPData(String urlString, String json) {
- try {
- URL url = new URL(urlString);
- HttpURLConnection urlConnection = (HttpURLConnection) url.OpenConnection();
- urlConnection.RequestMethod = "POST";
- urlConnection.DoOutput = true;
- byte[] _out = Encoding.UTF8.GetBytes(json);
- int lenght = _out.Length;
- urlConnection.SetFixedLengthStreamingMode(lenght);
- urlConnection.SetRequestProperty("Content-Type", "application/json");
- urlConnection.SetRequestProperty("charset", "utf-8");
- urlConnection.Connect();
- try {
- Stream str = urlConnection.OutputStream;
- str.Write(_out, 0, lenght);
- } catch (Exception ex) {
- System.Console.WriteLine("{0} Exception caught.", ex);
- }
- var status = urlConnection.ResponseCode;
- } catch (Exception ex) {
- System.Console.WriteLine("{0} Exception caught.", ex);
- }
- }
- public void PutHTTPData(String urlString, String json) {
- try {
- URL url = new URL(urlString);
- HttpURLConnection urlConnection = (HttpURLConnection) url.OpenConnection();
- urlConnection.RequestMethod = "PUT";
- urlConnection.DoOutput = true;
- byte[] _out = Encoding.UTF8.GetBytes(json);
- int lenght = _out.Length;
- urlConnection.SetFixedLengthStreamingMode(lenght);
- urlConnection.SetRequestProperty("Content-Type", "application/json");
- urlConnection.SetRequestProperty("charset", "utf-8");
- urlConnection.Connect();
- try {
- Stream str = urlConnection.OutputStream;
- str.Write(_out, 0, lenght);
- } catch (Exception ex) {
- System.Console.WriteLine("{0} Exception caught.", ex);
- }
- var status = urlConnection.ResponseCode;
- } catch (Exception ex) {
- System.Console.WriteLine("{0} Exception caught.", ex);
- }
- }
- public void DeleteHTTPData(String urlString, String json) {
- try {
- URL url = new URL(urlString);
- HttpURLConnection urlConnection = (HttpURLConnection) url.OpenConnection();
- urlConnection.RequestMethod = "DELETE";
- urlConnection.DoOutput = true;
- byte[] _out = Encoding.UTF8.GetBytes(json);
- int lenght = _out.Length;
- urlConnection.SetFixedLengthStreamingMode(lenght);
- urlConnection.SetRequestProperty("Content-Type", "application/json");
- urlConnection.SetRequestProperty("charset", "utf-8");
- urlConnection.Connect();
- try {
- Stream str = urlConnection.OutputStream;
- str.Write(_out, 0, lenght);
- } catch (Exception ex) {
- System.Console.WriteLine("{0} Exception caught.", ex);
- }
- var status = urlConnection.ResponseCode;
- } catch (Exception ex) {
- System.Console.WriteLine("{0} Exception caught.", ex);
- }
- }
- }
- }
Step 4
Now, open Solution Explorer-> Project Name-> Resources-> Layout-> Main.axml. Open this main layout file and add the following code.
(File Name: Main.axml)
(Folder Name: Layout)
Complete Code of UI
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:minWidth="25px" android:minHeight="25px">
- <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content">
- <TextView android:text="User :" android:textColor="#800000" android:layout_width="wrap_content" android:layout_height="wrap_content" />
- <EditText android:id="@+id/edtUser" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Enter User Name..." /> </LinearLayout>
- <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content">
- <Button android:id="@+id/btnAdd" android:text="Add" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="#008000" />
- <Button android:id="@+id/btnEdit" android:text="Edit" android:textColor="#0000FF" android:layout_width="match_parent" android:layout_height="wrap_content" />
- <Button android:id="@+id/btnDelete" android:text="Delete" android:textColor="#FF0000" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
- <ListView android:id="@+id/lstView" android:layout_width="match_parent" android:layout_height="wrap_content" />
- </LinearLayout>
Layout
Step 5
Next, we need to add a CustomAdapter class. Write the following code in it with appropriate namespaces.
(File Name: CustomAdapter)
- using Android.Content;
- using System.Collections.Generic;
- using Android.Views;
- using Android.Widget;
- using CloudNoSQL.Class;
- namespace CloudNoSQL.Helper {
- public class CustomAdapter: BaseAdapter {
- private Context mContext;
- private List < User > users;
- public CustomAdapter(Context mContext, List < User > users) {
- this.mContext = mContext;
- this.users = users;
- }
- public override int Count {
- get {
- return users.Count;
- }
- }
- public override Java.Lang.Object GetItem(int position) {
- {
- return position;
- }
- }
- public override long GetItemId(int position) {
- return position;
- }
- public override View GetView(int position, View convertView, ViewGroup parent) {
- LayoutInflater inflater = (LayoutInflater) mContext.GetSystemService(Context.LayoutInflaterService);
- View view = inflater.Inflate(Resource.Layout.row, null);
- TextView txtUser = view.FindViewById < TextView > (Resource.Id.txtUser);
- txtUser.Text = users[position].user;
- return view;
- }
- }
- }
Step 6
Next, we need to add another layout, so open Solution Explorer-> Project Name-> Resources-> Layout -> Right-click to Add-> New Item-> Layout. Give it a name as row and add the following code.
(File Name: row.axml)
(Folder Name: Layout)
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent">
- <TextView android:text="Large Text" android:textColor="#000000" android:textAppearance="?android:attr/textAppearanceLarge" android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/txtUser" />
- </LinearLayout>
Step 7
Let's open Solution Explorer-> Properties-> AndroidManifest and let's add the below code inside application tags.
- <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
- <uses-permission android:name="android.permission.INTERNET" />
Step 8
Now, go to Solution Explorer-> Project Name-> References. Then, right-click to "Manage NuGet Packages" and search for JSON. Install the Newtonsoft.Json Packages.
Step 10
Open Solution Explorer-> Project Name-> MainActivity. Open the main activity file and add the following code with appropriate namespaces.
Main Activity
- using Android.App;
- using Android.Widget;
- using Android.OS;
- using Android.Support.V7.App;
- using CloudNoSQL.Class;
- using System.Collections.Generic;
- using static Android.Widget.AdapterView;
- using Android.Views;
- using Java.Lang;
- using Newtonsoft.Json;
- using CloudNoSQL.Helper;
- namespace CloudNoSQL {
- [Activity(Label = "CloudNoSQL", MainLauncher = true, Theme = "@style/Theme.AppCompat.Light")]
- public class MainActivity: AppCompatActivity, IOnItemClickListener {
-
- private ListView lstView;
- private Button btnAdd, btnEdit, btnDelete;
- private EditText edtUser;
- private User SelectedUser = null;
- private List < User > users;
- public void OnItemClick(AdapterView parent, View view, int position, long id) {
- SelectedUser = users[position];
- edtUser.Text = SelectedUser.user;
- }
- protected override void OnCreate(Bundle savedInstanceState) {
- base.OnCreate(savedInstanceState);
-
- SetContentView(Resource.Layout.Main);
- lstView = FindViewById < ListView > (Resource.Id.lstView);
- btnAdd = FindViewById < Button > (Resource.Id.btnAdd);
- btnEdit = FindViewById < Button > (Resource.Id.btnEdit);
- btnDelete = FindViewById < Button > (Resource.Id.btnDelete);
- edtUser = FindViewById < EditText > (Resource.Id.edtUser);
-
- lstView.OnItemClickListener = this;
-
- btnAdd.Click += delegate {
- new PostData(edtUser.Text, this).Execute(Common.GetAddressAPI());
- };
-
- btnEdit.Click += delegate {
- new PutData(SelectedUser, edtUser.Text, this).Execute(Common.getAddressSingle(SelectedUser));
- };
-
- btnDelete.Click += delegate {
- new DeleteData(SelectedUser, edtUser.Text, this).Execute(Common.getAddressSingle(SelectedUser));
- };
-
- new GetData(this).Execute(Common.GetAddressAPI());
- }
-
- private class GetData: AsyncTask < string, Java.Lang.Void, string > {
- private ProgressDialog pd = new ProgressDialog(Application.Context);
- private MainActivity activity;
- public GetData(MainActivity activity) {
- this.activity = activity;
- }
- protected override void OnPreExecute() {
- base.OnPreExecute();
- pd.Window.SetType(WindowManagerTypes.SystemAlert);
- pd.SetTitle("Please wait...");
- pd.Show();
- }
- protected override string RunInBackground(params string[] @params) {
- string stream = null;
- string urlString = @params[0];
- HttpDataHandler http = new HttpDataHandler();
- stream = http.GetHTTPData(urlString);
- return stream;
- }
- protected override void OnPostExecute(string result) {
- base.OnPostExecute(result);
- activity.users = JsonConvert.DeserializeObject < List < User >> (result);
- CustomAdapter adapter = new CustomAdapter(Application.Context, activity.users);
- activity.lstView.Adapter = adapter;
- pd.Dismiss();
- }
- }
-
- private class PostData: AsyncTask < string, Java.Lang.Void, string > {
- private ProgressDialog pd = new ProgressDialog(Application.Context);
- string userName = "";
- private MainActivity mainActivity;
- public PostData(string userName, MainActivity mainActivity) {
- this.userName = userName;
- this.mainActivity = mainActivity;
- }
- protected override void OnPreExecute() {
- base.OnPreExecute();
- pd.Window.SetType(WindowManagerTypes.SystemAlert);
- pd.SetTitle("Please wait...");
- pd.Show();
- }
- protected override string RunInBackground(params string[] @params) {
- string urlString = @params[0];
- HttpDataHandler http = new HttpDataHandler();
- User user = new User();
- user.user = userName;
- string json = JsonConvert.SerializeObject(user);
- http.PostHTTPData(urlString, json);
- return string.Empty;
- }
- protected override void OnPostExecute(string result) {
- base.OnPostExecute(result);
- new GetData(mainActivity).Execute(Common.GetAddressAPI());
- pd.Dismiss();
- }
- }
-
- private class PutData: AsyncTask < string, Java.Lang.Void, string > {
- private ProgressDialog pd = new ProgressDialog(Application.Context);
- string newUser = "";
- private MainActivity mainActivity;
- User selectedUser = null;
- public PutData(User selectedUser, string newUser, MainActivity mainActivity) {
- this.newUser = newUser;
- this.mainActivity = mainActivity;
- this.selectedUser = selectedUser;
- }
- protected override void OnPreExecute() {
- base.OnPreExecute();
- pd.Window.SetType(WindowManagerTypes.SystemAlert);
- pd.SetTitle("Please wait...");
- pd.Show();
- }
- protected override string RunInBackground(params string[] @params) {
- string urlString = @params[0];
- HttpDataHandler http = new HttpDataHandler();
- selectedUser.user = newUser;
- string json = JsonConvert.SerializeObject(selectedUser);
- http.PutHTTPData(urlString, json);
- return string.Empty;
- }
- protected override void OnPostExecute(string result) {
- base.OnPostExecute(result);
- new GetData(mainActivity).Execute(Common.GetAddressAPI());
- pd.Dismiss();
- }
- }
-
- private class DeleteData: AsyncTask < string, Java.Lang.Void, string > {
- private ProgressDialog pd = new ProgressDialog(Application.Context);
- string newUser = "";
- private MainActivity mainActivity;
- User selectedUser = null;
- public DeleteData(User selectedUser, string newUser, MainActivity mainActivity) {
- this.newUser = newUser;
- this.mainActivity = mainActivity;
- this.selectedUser = selectedUser;
- }
- protected override void OnPreExecute() {
- base.OnPreExecute();
- pd.Window.SetType(WindowManagerTypes.SystemAlert);
- pd.SetTitle("Please wait...");
- pd.Show();
- }
- protected override string RunInBackground(params string[] @params) {
- string urlString = @params[0];
- HttpDataHandler http = new HttpDataHandler();
- selectedUser.user = newUser;
- string json = JsonConvert.SerializeObject(selectedUser);
- http.DeleteHTTPData(urlString, json);
- return string.Empty;
- }
- protected override void OnPostExecute(string result) {
- base.OnPostExecute(result);
- new GetData(mainActivity).Execute(Common.GetAddressAPI());
- pd.Dismiss();
- }
- }
- }
- }
Output