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()); } } }
<?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>
<?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 } }