In previous post we demonstrated how to use DotVVM to create CRUD application with Azure Cosmos DB as your data store.
In this post we will demonstrate how to do the same with Cloud Firestore by Google.
To know more about DotVVM Framework you can check its official website
What is Cloud Firestore?
Cloud Firestore is a flexible, scalable database for mobile, web, and server development from Firebase and Google Cloud Platform. It keeps your data in sync across client apps through realtime listener and offers offline support for mobile and web apps.
You can know more about Cloud Firebase here.
Install DotVVM extension
refer to previous post and follow the steps.
To know more about the DotVVM extension visit its page on visual studio marketplace:https://marketplace.visualstudio.com/items?itemName=TomasHerceg.DotVVM-VSExtension2019
Now you are ready to start coding with DotVVM framework. DotVVM extension installs DotVVM sample project which we will use to demonstrate how it is easy to connect to Cloud Firestore database from DotVVM application.
Create Cloud Firestore Project
To use cloud Firestore as your database you need to create a project on Firestore.
- Go to https://console.firebase.google.com/ and login with your google account or create new one.
Click on Add Project
Enter "dotvvm" as project name.
In next step, Disable Google Analytics for this project. It is recommended to enable it for real project.
-
Click on Create Project. it will take one or two mins to create your project. When it is ready click on continue.
-
From the left navigation pan, open database then click on Create database
In the popup window, select Start in test mode then click next.
Select the location of your database(you can keep the default selection) then Click Done.
Congratulation, your Cloud Firestore database is created and ready.
To be able to connect to your Firestore database from your application(server) you need to set the GOOGLE_APPLICATION_CREDENTIALS environment variable to point to JSON service account key file.
To setup your service account, go to https://cloud.google.com/docs/authentication/getting-started and follow the instructions.
DotVVM Web Application
In previous post you can find the complete steps for creating DotVVM web application. In this post we focus on code changes required to connect to Firestore database.
- Uninstall entity framework Sql Server related nuget package
Microsoft.EntityFrameworkCore.SqlServer
andMicrosoft.EntityFrameworkCore
As we will connect to Cloud Firestore database not Sql Server database - Install
Google.Cloud.Firestore
nuget package. This package is required to run CRUD operations against your firestore database from your web application. - Open appsettings.json file and remove the connection string. keeping it will not harm but we need our code to be clean.
- Delete DAL/StudentDbContext.cs file.
-
Open Startup.cs file and delete the following lines
services.AddEntityFrameworkSqlServer()
.AddDbContext<Studentdbcontext>(options =>
{
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
}); -
Open DAL/Entities/Student.cs file and add the following using statement
using Google.Cloud.Firestore;
Decorate the Student class with
[FirestoreData]
attribute and each property with[FirestoreProperty]
attribute. Also change the type ofEnrollmentDate
property to Timestamp instead ofDateTime
. The complete code of Student class will be
[FirestoreData]
public class Student
{
[FirestoreProperty]
public int Id { get; set; }
[FirestoreProperty]
public string FirstName { get; set; }
[FirestoreProperty]
public string LastName { get; set; }
[FirestoreProperty]
public string About { get; set; }
[FirestoreProperty]
public Timestamp EnrollmentDate { get; set; }
}
Those attributes are required and used to serialize/deserialize your entities from and to json objects. Timestamp
is the Firestore datatype used to represent date/time values.
-
Open Services/StudentService.cs file and add the following private properties to
StudentService
classprivate const string project = "dotvvm";
private const string collection = "students";where project is the name of your Firestore project and collection is the name of your database collection where you will insert/retrieve records
-
Replace the
GetAllStudentsAsync
method with the followingpublic async Task<List<StudentListModel>> GetAllStudentsAsync()
{
var studentsList = new List<Student>();
FirestoreDb db = FirestoreDb.Create(Project);
Query allStudentsQuery = db.Collection(Collection);
QuerySnapshot allStudentsQuerySnapshot = await allStudentsQuery.GetSnapshotAsync();
foreach (DocumentSnapshot documentSnapshot in allStudentsQuerySnapshot.Documents)
{
studentsList.Add(documentSnapshot.ConvertTo<Student>());
}
return studentsList.Select(
s => new StudentListModel
{
Id = s.Id,
FirstName = s.FirstName,
LastName = s.LastName
}
).ToList();
} -
Replace the
GetStudentByIdAsync
method with the followingpublic async Task<StudentListModel> GetStudentByIdAsync()
{
FirestoreDb db = FirestoreDb.Create(Project);
Query docRef = db.Collection(Collection).WhereEqualTo("Id", studentId).Limit(1);
QuerySnapshot snapshot = await docRef.GetSnapshotAsync();
if (snapshot.Count > 0)
{
Student student = snapshot.ElementAt(0).ConvertTo<Student>();
return new StudentDetailModel()
{
About = student.About,
EnrollmentDate = student.EnrollmentDate.ToDateTime(),
FirstName = student.FirstName,
Id = student.Id,
LastName = student.LastName
};
}
else
{
return null;
}
} -
Replace the
UpdateStudentAsync
method with the followingpublic async Task UpdateStudentAsync(StudentDetailModel student)
{
FirestoreDb db = FirestoreDb.Create(Project);
Query docRef = db.Collection(Collection).WhereEqualTo("Id", student.Id).Limit(1);
QuerySnapshot snapshot = await docRef.GetSnapshotAsync();
if (snapshot.Count > 0)
{
DocumentReference studentRef = db.Collection(Collection).Document(snapshot.ElementAt(0).Id);
Dictionary<string, object> updates = new Dictionary<string, object>
{
{ nameof(student.About), student.About},
{ nameof(student.EnrollmentDate), Timestamp.FromDateTime(student.EnrollmentDate.ToUniversalTime())},
{ nameof(student.FirstName), student.FirstName},
{ nameof(student.LastName), student.LastName}
};
await studentRef.UpdateAsync(updates);
}
} -
Replace the
InsertStudentAsync
method with the followingpublic async Task InsertStudentAsync(StudentDetailModel student)
{
var entity = new Student()
{
Id = new Random().Next(1, int.MaxValue),
FirstName = student.FirstName,
LastName = student.LastName,
About = student.About,
//create Timestamp from DateTime value
EnrollmentDate = Timestamp.FromDateTime(student.EnrollmentDate.ToUniversalTime())
};
FirestoreDb db = FirestoreDb.Create(Project);
var Id = Guid.NewGuid().ToString();
DocumentReference docRef = db.Collection(Collection).Document(Id);
await docRef.SetAsync(entity);
} -
Replace the
DeleteStudentAsync
method with the followingpublic async Task DeleteStudentAsync(int studentId)
{
FirestoreDb db = FirestoreDb.Create(Project);
Query docRef = db.Collection(Collection).WhereEqualTo("Id", studentId).Limit(1);
QuerySnapshot snapshot = await docRef.GetSnapshotAsync();
if (snapshot.Count > 0)
{
DocumentReference studentRef = db.Collection(Collection).Document(snapshot.ElementAt(0).Id);
await studentRef.DeleteAsync();
}
} -
Run your application and if there is no error you will see the following page in your browser
-
Click on New Item and fill the form then click Add
-
Congratulation, you added your student to students Firestore collection
-
Go to your Firestore database, it should look like
notice that, Firestore is created a student collection and inserted your student entity as
JSON
document and also notice how it represents theEnrollmentDate
value as timestamp.
Summary
In this article we demonstrated how to create a sample DotVVM web application, Cloud Firestore database and perform CRUD operations as we used to do with SQL Server database or any other relational database. We have done changes in the sample project code to twist it from using Entity Framework Code First approach (SQL Server) to use Google Cloud FireStore .Net SDK.
You can find the complete source code on github
Top comments (0)