Search This Blog

Monday 6 December 2021

Xamarin Form CRUD Operation using Firebase Realtime Database

 



Github URL: https://github.com/mistrypragnesh40/FirebaseDemo
Youtube URL: https://youtu.be/LYAxYNN8s_s

Packages Required









Models
EmployeeModel.cs

using System;

using System.Collections.Generic;
using System.Text;
 
namespace FirebaseDemo.Models
{
    public class EmployeeModel
    {
        public string Key { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Gender { get; set; }
        public string MobileNumber { get; set; }
        public string Position { get; set; }
        public string Email { get; set; }
    }
}
Setting.cs
using System;
using System.Collections.Generic;
using System.Text;
 
namespace FirebaseDemo.Models
{
    public static class Setting
    {
        internal const string FireBaseDatabaseUrl = "";
        internal const string FireBaseSeceret = "";
    }
}
 
Services.cs
IEmployeeService.cs
using FirebaseDemo.Models;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
 
namespace FirebaseDemo.Services.Interfaces
{
    public interface IEmployeeService
    {
        Task<bool> AddOrUpdateEmployee(EmployeeModel employeeModel);
        Task<bool> DeleteEmployee(string key);
        Task<List<EmployeeModel>> GetAllEmployee();
    }
}
 
EmployeeService.cs
using Firebase.Database;
using Firebase.Database.Query;
using FirebaseDemo.Models;
using FirebaseDemo.Services.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace FirebaseDemo.Services.Implementations
{
    public class EmployeeService : IEmployeeService
    {
        FirebaseClient firebase = new FirebaseClient(Setting.FireBaseDatabaseUrl, new FirebaseOptions
        {
            AuthTokenAsyncFactory = () => Task.FromResult(Setting.FireBaseSeceret)
        });
 
        public async Task<bool> AddOrUpdateEmployee(EmployeeModel employeeModel)
        {
            if (!string.IsNullOrWhiteSpace(employeeModel.Key))
            {
                try
                {
                    await firebase.Child(nameof(EmployeeModel)).Child(employeeModel.Key).PutAsync(employeeModel);
                    return true;
                }
                catch(Exception ex)
                {
                    return false;
                }
            }
            else
            {
                var response = await firebase.Child(nameof(EmployeeModel)).PostAsync(employeeModel);
                if (response.Key != null)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
 
        }
 
        public async Task<bool> DeleteEmployee(string key)
        {
            try
            {
                await firebase.Child(nameof(EmployeeModel)).Child(key).DeleteAsync();
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }
 
        public async Task<List<EmployeeModel>> GetAllEmployee()
        {
            return (await firebase.Child(nameof(EmployeeModel)).OnceAsync<EmployeeModel>()).Select(f => new EmployeeModel
            {
                Email = f.Object.Email,
                FirstName = f.Object.FirstName,
                Gender = f.Object.Gender,
                LastName = f.Object.LastName,
                MobileNumber = f.Object.MobileNumber,
                Position = f.Object.Position,
                Key = f.Key
            }).ToList();
 
        }
    }
}
 

Views
MainPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="FirebaseDemo.MainPage">
 
    <StackLayout>
        <Frame BackgroundColor="#2196F3" Padding="24" CornerRadius="0">
            <Label Text="Welcome to Xamarin.Forms!" HorizontalTextAlignment="Center" TextColor="White" FontSize="36"/>
        </Frame>
        <Label Text="Start developing now" FontSize="Title" Padding="30,10,30,10"/>
        <Button Text="Add Employee" x:Name="addEmployee" Clicked="addEmployee_Clicked" />
        <Button Text="Show All Employee" x:Name="showEmployee" Clicked="showEmployee_Clicked" />
    </StackLayout>
 
</ContentPage>
 
MainPage.xaml.cs
using FirebaseDemo.Views;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
 
namespace FirebaseDemo
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
        }
 
        private void addEmployee_Clicked(object sender, EventArgs e)
        {
            Navigation.PushAsync(new AddUpdateEmployee());
        }
 
        private void showEmployee_Clicked(object sender, EventArgs e)
        {
            Navigation.PushAsync(new EmployeeList());
        }
    }
}
 


AddUpdateEmployee.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:viewmodels="clr-namespace:FirebaseDemo.ViewModels"
             x:DataType="viewmodels:AddUpdateEmployeePageViewModel"
             Title="Add/Update Employee"
             x:Class="FirebaseDemo.Views.AddUpdateEmployee">
    <ContentPage.Content>
        <StackLayout>
            <Entry Placeholder="First Name" Text="{Binding EmployeeDetail.FirstName}" />
            <Entry Placeholder="Last Name" Text="{Binding EmployeeDetail.LastName}"  />
            <Entry Placeholder="Gender" Text="{Binding EmployeeDetail.Gender}"  />
            <Entry Placeholder="Mobile Number" Text="{Binding EmployeeDetail.MobileNumber}"  Keyboard="Numeric" />
            <Entry Placeholder="Position" Text="{Binding EmployeeDetail.Position}"   />
            <Entry Placeholder="Email" Text="{Binding EmployeeDetail.Email}"  />
 
            <Button Text="Save Details" Command="{Binding SaveEmployeeCommand}" />
        </StackLayout>
    </ContentPage.Content>
</ContentPage>


EmployeeList.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
             xmlns:viewmodels="clr-namespace:FirebaseDemo.ViewModels"
             xmlns:models="clr-namespace:FirebaseDemo.Models"
             x:DataType="viewmodels:EmployeeListPageViewModel"
             Title="Employee List"
             x:Class="FirebaseDemo.Views.EmployeeList">
    <ContentPage.Content>
        <StackLayout Margin="10,0,10,0">
            <ActivityIndicator IsVisible="{Binding IsBusy}" IsRunning="True" />
 
            <RefreshView Command="{Binding RefreshCommand}" IsRefreshing="{Binding IsRefreshing}" >
                <CollectionView ItemsSource="{Binding Employees}">
                    <CollectionView.ItemTemplate>
                        <DataTemplate x:DataType="models:EmployeeModel">
                            <StackLayout Margin="10,5,10,0">
                                <StackLayout Orientation="Horizontal">
                                    <Label Text="First Name: " />
                                    <Label Text="{Binding FirstName}" />
                                </StackLayout>
                                <StackLayout Orientation="Horizontal">
                                    <Label Text="Last Name: " />
                                    <Label Text="{Binding LastName}" />
                                </StackLayout>
                                <StackLayout Orientation="Horizontal">
                                    <Label Text="Email: " />
                                    <Label Text="{Binding Email}" />
                                </StackLayout>
                                <StackLayout Orientation="Horizontal">
                                    <Label Text="Gender: " />
                                    <Label Text="{Binding Gender}" />
                                </StackLayout>
                                <StackLayout Orientation="Horizontal">
                                    <Label Text="Position: " />
                                    <Label Text="{Binding Position}" />
                                </StackLayout>
                                <BoxView HeightRequest="1" Color="Gray" />
 
                                <StackLayout.GestureRecognizers>
                                    <TapGestureRecognizer Command="{Binding Source={x:RelativeSource AncestorType={x:Type viewmodels:EmployeeListPageViewModel}},Path=SelectedEmployeeCommand}" CommandParameter="{Binding .}" />
                                </StackLayout.GestureRecognizers>
                            </StackLayout>
                        </DataTemplate>
                    </CollectionView.ItemTemplate>
                </CollectionView>
            </RefreshView>
 
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

ViewModels
BaseViewModel.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Text;
 
namespace FirebaseDemo.ViewModels
{
    public class BaseViewModel : INotifyPropertyChanged
    {
 
        #region Properties
        private bool _isBusy;
        public bool IsBusy
        {
            get => _isBusy;
            set => SetProperty(ref _isBusy, value);
        }
        #endregion
 
        protected bool SetProperty<T>(ref T backingStore, T value,
     [CallerMemberName] string propertyName = "",
     Action onChanged = null)
        {
            if (EqualityComparer<T>.Default.Equals(backingStore, value))
                return false;
 
            backingStore = value;
            onChanged?.Invoke();
            OnPropertyChanged(propertyName);
            return true;
        }
 
        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
        {
            var changed = PropertyChanged;
            if (changed == null)
                return;
 
            changed.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion
    }
}
 
AddUpdateEmployeePageViewModel.cs
using FirebaseDemo.Models;
using FirebaseDemo.Services.Implementations;
using FirebaseDemo.Services.Interfaces;
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Input;
using Xamarin.Forms;
 
namespace FirebaseDemo.ViewModels
{
    public class AddUpdateEmployeePageViewModel : BaseViewModel
    {
        #region Properties
        private readonly IEmployeeService _employeeService;
 
        private EmployeeModel _employeeDetail = new EmployeeModel();
        public EmployeeModel EmployeeDetail
        {
            get => _employeeDetail;
            set => SetProperty(ref _employeeDetail, value);
        }
        #endregion
 
        #region Constructor
        public AddUpdateEmployeePageViewModel()
        {
            _employeeService = DependencyService.Resolve<IEmployeeService>();
        }
 
        public AddUpdateEmployeePageViewModel(EmployeeModel employeeResponse)
        {
            _employeeService = DependencyService.Resolve<IEmployeeService>();
            EmployeeDetail =  new EmployeeModel
            {
                FirstName = employeeResponse.FirstName,
                LastName = employeeResponse.LastName,
                Key = employeeResponse.Key,
                Gender = employeeResponse.Gender,
                Email = employeeResponse.Email,
                MobileNumber =employeeResponse.MobileNumber,
                Position = employeeResponse.Position
            };
        }
        #endregion
 
        #region Commands
        public ICommand SaveEmployeeCommand => new Command(async () =>
        {
            if (IsBusy) return;
            IsBusy = true;
            bool res = await _employeeService.AddOrUpdateEmployee(EmployeeDetail);
            if (res)
            {
 
                if (!string.IsNullOrWhiteSpace(EmployeeDetail.Key))
                {
                    await App.Current.MainPage.DisplayAlert("Success!", "Record Updated successfully.", "Ok");
                }
                else
                {
                    EmployeeDetail = new EmployeeModel() { };
                    await App.Current.MainPage.DisplayAlert("Success!", "Record added successfully.", "Ok");
                }
            }
            IsBusy = false;
        });
        #endregion
    }
}
 
EmployeeListPageViewModel.cs
using FirebaseDemo.Models;
using FirebaseDemo.Services.Interfaces;
using FirebaseDemo.Views;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;
 
namespace FirebaseDemo.ViewModels
{
    public class EmployeeListPageViewModel : BaseViewModel
    {
        #region Properties
        private bool _isRefreshing;
        public bool IsRefreshing
        {
            get => _isRefreshing;
            set => SetProperty(ref _isRefreshing, value);
        }
 
        private readonly IEmployeeService _employeeService;
 
        public ObservableCollection<EmployeeModel> Employees { get; set; } = new ObservableCollection<EmployeeModel>();
        #endregion
 
        #region Constructor
        public EmployeeListPageViewModel()
        {
            _employeeService = DependencyService.Resolve<IEmployeeService>();
            GetAllEmployee();
        }
        #endregion
 
        #region Methods
        private void GetAllEmployee()
        {
            IsBusy = true;
            Task.Run(async () =>
            {
                var employeeLIst = await _employeeService.GetAllEmployee();
 
                Device.BeginInvokeOnMainThread(() =>
                {
 
                    Employees.Clear();
                    if (employeeLIst?.Count > 0)
                    {
                        foreach (var employee in employeeLIst)
                        {
                            Employees.Add(employee);
                        }
                    }
                    IsBusy = IsRefreshing = false;
                });
 
            });
        }
        #endregion
 
        #region Commands
 
        public ICommand RefreshCommand => new Command(() =>
        {
            IsRefreshing = true;
            GetAllEmployee();
        });
 
        public ICommand SelectedEmployeeCommand => new Command<EmployeeModel>(async (employee) =>
        {
            if (employee != null)
            {
                var response = await App.Current.MainPage.DisplayActionSheet("Options!", "Cancel", null, "Update Employee", "Delete Employee");
 
                if (response == "Update Employee")
                {
                    await App.Current.MainPage.Navigation.PushAsync(new AddUpdateEmployee(employee));
                }
                else if (response == "Delete Employee")
                {
                    IsBusy = true;
                    bool deleteResponse = await _employeeService.DeleteEmployee(employee.Key);
                    if (deleteResponse)
                    {
                        GetAllEmployee();
                    }
                }
            }
        });
        #endregion
    }
}
 





Popular Posts