... Cloud Firestore is a flexible, scalable database for mobile, web, and server development from Firebase and Google Cloud. Like Firebase Realtime Database, it keeps your data in sync across client apps through realtime listeners and offers offline support for mobile and web so you can build responsive apps that work regardless of network latency or Internet connectivity...
Sounds cool, so how do I set it up with .Net Core (dotnet)?
It's very simple.
I won't go into detail on how to setup firebase using console, there are plenty of tutorials out there. What we will need is the service account json file.
Let's start with the important part and create FirebaseProvider
for generic use.
Firebase Provider
Ah yeah and make sure you have this nuget package installed:
<PackageReference Include="Google.Cloud.Firestore" Version="2.4.0" />
public class FirestoreProvider
{
private readonly FirestoreDb _fireStoreDb = null!;
public FirestoreProvider(FirestoreDb fireStoreDb)
{
_fireStoreDb = fireStoreDb;
}
public async Task AddOrUpdate<T>(T entity, CancellationToken ct) where T : IFirebaseEntity
{
var document = _fireStoreDb.Collection(typeof(T).Name).Document(entity.Id);
await document.SetAsync(entity, cancellationToken: ct);
}
public async Task<T> Get<T>(string id, CancellationToken ct) where T : IFirebaseEntity
{
var document = _fireStoreDb.Collection(typeof(T).Name).Document(id);
var snapshot = await document.GetSnapshotAsync(ct);
return snapshot.ConvertTo<T>();
}
public async Task<IReadOnlyCollection<T>> GetAll<T>(CancellationToken ct) where T : IFirebaseEntity
{
var collection = _fireStoreDb.Collection(typeof(T).Name);
var snapshot = await collection.GetSnapshotAsync(ct);
return snapshot.Documents.Select(x => x.ConvertTo<T>()).ToList();
}
public async Task<IReadOnlyCollection<T>> WhereEqualTo<T>(string fieldPath, object value, CancellationToken ct) where T : IFirebaseEntity
{
return await GetList<T>(_fireStoreDb.Collection(typeof(T).Name).WhereEqualTo(fieldPath, value), ct);
}
// just add here any method you need here WhereGreaterThan, WhereIn etc ...
private static async Task<IReadOnlyCollection<T>> GetList<T>(Query query, CancellationToken ct) where T : IFirebaseEntity
{
var snapshot = await query.GetSnapshotAsync(ct);
return snapshot.Documents.Select(x => x.ConvertTo<T>()).ToList();
}
}
Usage
Inject it to your whatever it's going to use it.
private readonly FirestoreProvider _firestoreProvider;
public SampleEndpoint(FirestoreProvider firestoreProvider)
{
_firestoreProvider = firestoreProvider;
}
... and here is how you would actually use it:
// Add or Update
var user = new User("Artur");
await _firestoreProvider.AddOrUpdate(user, cancellationToken);
// Get by Id
var user = await _firestoreProvider.Get<User>("306f19a85136414b868ff7ba56c3f0a8", cancellationToken);
// Get all (use it wisely*)
var allUsers = await _firestoreProvider.GetAll<User>(cancellationToken);
// Query by first name (for example)
var users = await _firestoreProvider.WhereEqualTo<User>(nameof(Api.Data.User.FirstName), "Artur", ct);
Data model
Now the boooooring part.
Our simplified data model:
[FirestoreData]
public class User : IFirebaseEntity
{
[FirestoreProperty]
public string Id { get; set; }
[FirestoreProperty]
public string FirstName { get; set; }
public User()
{
}
public User(string firstName)
{
Id = Guid.NewGuid().ToString("N");
FirstName = firstName;
}
}
The interfaces that forces to create Id which would be used as document id. We will use string version of Guid
for that purpose.
public interface IFirebaseEntity
{
public string Id { get; set; }
}
Provider registration
Register our provider in Startup.cs
within ConfigureServices
.
services.AddSingleton(_ => new FirestoreProvider(
new FirestoreDbBuilder
{
ProjectId = firebaseSettings.ProjectId,
JsonCredentials = firebaseJson // <-- service account json file
}.Build()
));
Firebase service account json
If you want a quick and dirty way of loading one without json files floating around your solution you can just hard code them into a class:
public class FirebaseSettings
{
[JsonPropertyName("project_id")]
public string ProjectId => "that-rug-really-tied-the-room-together-72daa";
[JsonPropertyName("private_key_id")]
public string PrivateKeyId => "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
// ... and so on
}
In Startup.cs
within ConfigureServices
.
var firebaseJson = JsonSerializer.Serialize(new FirebaseSettings());
... and you are done!
If you want to have plural names for your collections just modify FirestoreProvider
so that collection gets s
:
_fireStoreDb.Collection($"{typeof(T).Name}s")
Thank you for reading!
If you enjoyed this post and want to stay updated, follow me on Twitter for the latest updates and check out my projects on GitHub.
May the code be with you!
Top comments (0)