{"id":90192,"date":"2023-06-12T08:00:54","date_gmt":"2023-06-12T06:00:54","guid":{"rendered":"https:\/\/drafts.code-maze.com\/?p=90192"},"modified":"2024-01-31T15:32:52","modified_gmt":"2024-01-31T14:32:52","slug":"dotnet-firebase","status":"publish","type":"post","link":"https:\/\/code-maze.com\/dotnet-firebase\/","title":{"rendered":"Introduction to Firebase in .NET"},"content":{"rendered":"<p>When designing and building applications, often we find ourselves needing various third-party services, such as databases, push notifications, hosting, authentication, and many other complex features. Firebase, built by Google, is an all-in-one application development platform that provides all this functionality and more, giving us an easy-to-use platform to develop and scale our applications.<\/p>\n<div style=\"padding: 20px; border-left: 5px #dc2323 solid; display: block; margin-bottom: 20px; box-shadow: 1px 1px 5px 0px lightgrey;\">To download the source code for this article, you can visit our <a href=\"https:\/\/github.com\/CodeMazeBlog\/CodeMazeGuides\/tree\/main\/dotnet-client-libraries\/Firebase\" target=\"_blank\" rel=\"nofollow noopener\">GitHub repository<\/a>.<\/div>\n<p>Let&#8217;s start by understanding some of the features Firebase provides.<\/p>\n<h2>What is Firebase?<\/h2>\n<p><strong>Firebase is a service offered by Google for developing and scaling mobile, web, and desktop applications.<\/strong> It originally launched in 2011, with a single service, the Realtime Database, which as the name suggests, is a real-time, NoSQL database that allows storing and syncing of data between users.<\/p>\n<p>Now, Firebase is much more than just a NoSQL database. Let&#8217;s look at some of the features it offers:<\/p>\n<ul>\n<li><strong>Authentication<\/strong>: an end-to-end authentication system, allowing users to authenticate to our applications using simple email and password accounts, through to social logins with Google, Facebook, GitHub, and many more.<\/li>\n<li><strong>Cloud messaging<\/strong>: Firebase focuses a lot on the mobile application market, so we need to send and receive notifications to Android and iOS devices frequently, which is covered by the cloud messaging functionality.<\/li>\n<li><strong>Hosting<\/strong>: we need somewhere to host our applications, which is where the Firebase hosting features come into play. It allows for simple previewing, deployment, and rollback of our applications.<\/li>\n<li><strong>Cloud storage<\/strong>: More often than not, we want to store files for our users, such as photos and videos. Firebase provides a fast and reliable cloud storage platform for handling these scenarios.<\/li>\n<\/ul>\n<h2><strong>Create Firebase Project<\/strong><\/h2>\n<p>There are various client libraries for different programming languages, including .NET, that allow us to interact and develop applications with Firebase. There is a great <a href=\"https:\/\/github.com\/googleapis\/google-cloud-dotnet\" target=\"_blank\" rel=\"nofollow noopener\">list of the available libraries on GitHub<\/a>, a few of which we&#8217;ll explore in this article. To start, let&#8217;s create a new web application using the Visual Studio Project Wizard or the\u00a0<code>dotnet new webapp<\/code> command.<\/p>\n<p>To kick things off, we need a Firebase project. <strong>A<\/strong> <strong>Firebase project is a top-level entity that we use to manage the various services<\/strong> on offer. We create Firebase projects from the Firebase<a href=\"https:\/\/console.firebase.google.com\/\" target=\"_blank\" rel=\"nofollow noopener\"> console<\/a>, so let&#8217;s start with that.<\/p>\n<p>With our project created, let&#8217;s retrieve the Project ID as we&#8217;ll need this later on for interacting with various services.<\/p>\n<p>To retrieve this ID, from the project overview, navigate to\u00a0<strong>Project settings<\/strong>:<\/p>\n<p><a href=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/06\/firebase-project-settings-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-90196\" src=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/06\/firebase-project-settings-1.png\" alt=\"firebase project settings\" width=\"417\" height=\"167\" srcset=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/06\/firebase-project-settings-1.png 417w, https:\/\/code-maze.com\/wp-content\/uploads\/2023\/06\/firebase-project-settings-1-300x120.png 300w\" sizes=\"auto, (max-width: 417px) 100vw, 417px\" \/><\/a><\/p>\n<p>From here, we&#8217;ll see the project details, including the Project ID:<\/p>\n<p><a href=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/06\/firebase-project-id-3.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-90197\" src=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/06\/firebase-project-id-3.png\" alt=\"firebase project id\" width=\"454\" height=\"270\" srcset=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/06\/firebase-project-id-3.png 454w, https:\/\/code-maze.com\/wp-content\/uploads\/2023\/06\/firebase-project-id-3-300x178.png 300w\" sizes=\"auto, (max-width: 454px) 100vw, 454px\" \/><\/a><\/p>\n<p>Depending on the name of the project, the ID may be different. Take note of this for use later on.<\/p>\n<h2>Authenticate With Firebase<\/h2>\n<p>With our new Firebase project created, we need to configure our authentication. <strong>Firebase handles authentication with service accounts, which allows us to authenticate with multiple Firebase features programmatically.<\/strong><\/p>\n<p>Firebase automatically creates a service account for us when we create a project, so to retrieve the credentials, we navigate to <strong>Project settings<\/strong>, then\u00a0<strong>Service<\/strong> <strong>accounts,<\/strong> and generate a new private key:<\/p>\n<p><a href=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/06\/generate-private-key-3.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-90198 size-full\" src=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/06\/generate-private-key-3.png\" alt=\"firebase generate private key\" width=\"799\" height=\"662\" srcset=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/06\/generate-private-key-3.png 799w, https:\/\/code-maze.com\/wp-content\/uploads\/2023\/06\/generate-private-key-3-300x249.png 300w, https:\/\/code-maze.com\/wp-content\/uploads\/2023\/06\/generate-private-key-3-768x636.png 768w\" sizes=\"auto, (max-width: 799px) 100vw, 799px\" \/><\/a><\/p>\n<p>This downloads a JSON configuration file with the required credentials. Keep a record of where this is saved as we&#8217;ll use this next.<\/p>\n<p>There are a couple of different methods to authenticate with the service account credentials. The simplest method is to set the <code>GOOGLE_APPLICATION_CREDENTIALS<\/code> environment variable to the file path for the JSON file we just downloaded.\u00a0<\/p>\n<p>Let&#8217;s do this in our <code>Program<\/code> class:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-highlight=\"3\">var builder = WebApplication.CreateBuilder(args);\r\n\r\nEnvironment.SetEnvironmentVariable(\"GOOGLE_APPLICATION_CREDENTIALS\", @\"&lt;PATH_TO_CREDENTIALS_FILE\");\r\n\r\nvar app = builder.Build();<\/pre>\n<p>Here, we use the\u00a0<code>SetEnvironmentVariable()<\/code> method to set up our authentication. Note that we are using the <code>@<\/code> symbol, which allows us to define a <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/tokens\/verbatim\" target=\"_blank\" rel=\"nofollow noopener\">verbatim string literal<\/a> for our file path, avoiding the need for any character escaping.<\/p>\n<p>With our authentication configured, let&#8217;s take a look at the first of the Firebase services we&#8217;ll cover, Firestore.<\/p>\n<h2>Firestore in .NET<\/h2>\n<p><strong><a href=\"https:\/\/firebase.google.com\/products\/firestore\" target=\"_blank\" rel=\"nofollow noopener\">Firestore<\/a> is the newer version of Firebase&#8217;s low-latency, real-time databases that allows us to store JSON documents.<\/strong><\/p>\n<p>First, let&#8217;s add the Firestore NuGet packages to our project:<\/p>\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"powershell\">Install-Package Google.Cloud.Firestore<\/code><\/p>\n<p>For our project, we&#8217;ll create a shoe website, so let&#8217;s create a class to model our domain:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public class Shoe\r\n{\r\n    public required string Id { get; set; }\r\n\r\n    public required string Name { get; set; }\r\n\r\n    public required string Brand { get; set; }\r\n\r\n    public decimal Price { get; set; }\r\n}<\/pre>\n<p>Firestore is a document database and our entities will be saved as JSON, so let&#8217;s create a JSON-friendly version of our <code>Shoe<\/code> class, that we&#8217;ll configure to allow Firestore to work with it:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">[FirestoreData]\r\npublic class ShoeDocument\r\n{\r\n    [FirestoreDocumentId]\r\n    public string Id { get; set; }\r\n\r\n    [FirestoreProperty]\r\n    public required string Name { get; set; }\r\n\r\n    [FirestoreProperty]\r\n    public required string Brand { get; set; }\r\n\r\n    [FirestoreProperty]\r\n    public required string Price { get; set; }\r\n}<\/pre>\n<p>This time, we define the same properties, but decorate them with the <code>FirestoreProperty<\/code> attribute, letting Firestore know we want to save these properties in the store. We use the <code>FirestoreDocumentId<\/code> attribute for the <code>Id<\/code> property, which tells Firestore to populate this property with the document Id.<\/p>\n<p>Furthermore, we decorate the class with the <code>FirestoreData<\/code> attribute, again letting Firestore know this is a model that will be stored in a database.<\/p>\n<p>Note here that we define the <code>Price<\/code> property as a <code>string<\/code> instead of a decimal. This is because Firestore doesn&#8217;t support decimals as one of its <a href=\"https:\/\/firebase.google.com\/docs\/firestore\/manage-data\/data-types\" target=\"_blank\" rel=\"nofollow noopener\">data types<\/a>.<\/p>\n<p>Next, let&#8217;s create a service for interacting with Firestore:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public class FirestoreService : IFirestoreService\r\n{\r\n    private readonly FirestoreDb _firestoreDb;\r\n    private const string _collectionName = \"Shoes\";\r\n\r\n    public FirestoreService(FirestoreDb firestoreDb)\r\n    {\r\n    \t_firestoreDb = firestoreDb;\r\n    }\r\n\r\n    public async Task&lt;List&lt;Shoe&gt;&gt; GetAll()\r\n    {\r\n    \tvar collection = _firestoreDb.Collection(_collectionName);\r\n    \tvar snapshot = await collection.GetSnapshotAsync();\r\n  \r\n    \tvar shoeDocuments = snapshot.Documents.Select(s =&gt; s.ConvertTo&lt;ShoeDocument&gt;()).ToList();\r\n\r\n    \treturn shoeDocuments.Select(ConvertDocumentToModel).ToList();\r\n    }\r\n\r\n    public async Task AddAsync(Shoe shoe)\r\n    {\r\n        var collection = _firestoreDb.Collection(_collectionName);\r\n        var shoeDocument = ConvertModelToDocument(shoe);\r\n\r\n        await collection.AddAsync(shoeDocument);\r\n    }\r\n\r\n    private static Shoe ConvertDocumentToModel(ShoeDocument shoeDocument)\r\n    {\r\n        return new Shoe\r\n        {\r\n            Id = shoeDocument.Id,\r\n            Name = shoeDocument.Name,\r\n            Brand = shoeDocument.Brand,\r\n            Price = decimal.Parse(shoeDocument.Price)\r\n        };\r\n    }\r\n\r\n    private static ShoeDocument ConvertModelToDocument(Shoe shoe)\r\n    {\r\n        return new ShoeDocument\r\n        {\r\n            Id = shoe.Id,\r\n            Name = shoe.Name,\r\n            Brand = shoe.Brand,\r\n            Price = shoe.Price.ToString()\r\n        };\r\n    }\r\n}<\/pre>\n<p>Here, we start by defining our <code>_collectionName<\/code> and a <code>FirestoreDb<\/code> field, which we use <a href=\"https:\/\/code-maze.com\/dependency-injection-aspnet\/\" target=\"_blank\" rel=\"noopener\">dependency injection<\/a> to inject into the constructor.<\/p>\n<p>Next, we define two methods.\u00a0The <code>GetAll()<\/code> method retrieves a snapshot of the shoe collection, which we then convert to our <code>ShoeDocument<\/code> model using the <code>ConvertTo()<\/code> method. Finally, we use our private <code>ConvertDocumentToModel()<\/code> method to return a <code>List&lt;Shoe&gt;<\/code>.<\/p>\n<p>The <code>Add()<\/code> method uses the <code>ConvertModelToDocument()<\/code> method so we use the correct model that Firestore expects, finally calling the <code>AddAsync()<\/code> method to add the new shoe.<\/p>\n<p>Let&#8217;s register this service with the DI framework in the <code>Program<\/code> class:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-highlight=\"5-7\">var builder = WebApplication.CreateBuilder(args);\r\n\r\n\/\/ code removed for brevity\r\n\r\nbuilder.Services.AddSingleton&lt;IFirestoreService&gt;(s =&gt; new FirestoreService(\r\n    FirestoreDb.Create(\"&lt;PROJECT_ID&gt;\")\r\n    ));\r\n\r\nvar app = builder.Build();<\/pre>\n<p>We add the <code>FirestoreService<\/code> as a singleton, using the <code>Create()<\/code> method from the <code>FirestoreDb<\/code> class to create our database. Here, we use the Project ID for our Firebase project we took note of earlier.<\/p>\n<h3>Interact With Firestore Model<\/h3>\n<p>Now that we&#8217;ve configured our <code>FirestoreService<\/code> and required models, let&#8217;s create a few <a href=\"https:\/\/code-maze.com\/views-partial-views-and-layouts-in-asp-net-core-mvc\/\" target=\"_blank\" rel=\"noopener\">Razor Pages<\/a> to interact with the database.<\/p>\n<p>First, let&#8217;s create a page for displaying all our shoes in Firestore:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">@page\r\n@model Firebase.Pages.Firestore.IndexModel\r\n@{\r\n    ViewData[\"Title\"] = \"Shoes\";\r\n}\r\n\r\n&lt;h2&gt;Shoes&lt;\/h2&gt;\r\n&lt;p&gt;&lt;a asp-page=\"Create\"&gt;Create New&lt;\/a&gt;&lt;\/p&gt;\r\n&lt;table class=\"table\"&gt;\r\n    &lt;thead&gt;\r\n        &lt;tr&gt;\r\n            &lt;th&gt;\r\n                &lt;label&gt;Id&lt;\/label&gt;\r\n            &lt;\/th&gt;\r\n            &lt;th&gt;\r\n                &lt;label&gt;Name&lt;\/label&gt;\r\n            &lt;\/th&gt;\r\n            &lt;th&gt;\r\n                &lt;label&gt;Brand&lt;\/label&gt;\r\n            &lt;\/th&gt;\r\n            &lt;th&gt;\r\n                &lt;label&gt;Price&lt;\/label&gt;\r\n            &lt;\/th&gt;\r\n        &lt;\/tr&gt;\r\n    &lt;\/thead&gt;\r\n    &lt;tbody&gt;\r\n        @foreach (var shoe in Model.Shoes)\r\n        {\r\n            &lt;tr&gt;\r\n                &lt;td&gt;\r\n                    &lt;label&gt;@shoe.Id&lt;\/label&gt;\r\n                &lt;\/td&gt;\r\n                &lt;td&gt;\r\n                    &lt;label&gt;@shoe.Name&lt;\/label&gt;\r\n                &lt;\/td&gt;\r\n                &lt;td&gt;\r\n                    &lt;label&gt;@shoe.Brand&lt;\/label&gt;\r\n                &lt;\/td&gt;\r\n                &lt;td&gt;\r\n                    &lt;label&gt;@shoe.Price&lt;\/label&gt;\r\n                &lt;\/td&gt;\r\n            &lt;\/tr&gt;\r\n        }\r\n    &lt;\/tbody&gt;\r\n&lt;\/table&gt;\r\n<\/pre>\n<p>Here, we have a very basic table view of all the shoes in our Firestore database. Let&#8217;s retrieve these from the store whenever we navigate to the page:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public class IndexModel : PageModel\r\n{\r\n    private readonly IFirestoreService _firestoreService;\r\n\r\n    public List&lt;Shoe&gt;? Shoes;\r\n\r\n    public IndexModel(IFirestoreService firestoreService)\r\n    {\r\n        _firestoreService = firestoreService;\r\n    }\r\n\r\n    public async Task OnGetAsync()\r\n    {\r\n        Shoes = await _firestoreService.GetAll();\r\n    }\r\n}<\/pre>\n<p>In our <code>IndexModel<\/code> code-behind, we inject our <code>IFirestoreService<\/code> interface which we use in the <code>OnGetAsync()<\/code> method to retrieve our list of shoes.<\/p>\n<p>This is great, but we don&#8217;t have any shoes yet, so let&#8217;s add a page for creating shoes:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">@page\r\n@model Firebase.Pages.Firestore.CreateModel\r\n@{\r\n    ViewData[\"Title\"] = \"Create Shoe\";\r\n}\r\n\r\n&lt;h2&gt;Create Shoe&lt;\/h2&gt;\r\n\r\n&lt;div class=\"row\"&gt;\r\n    &lt;div class=\"col-md-4\"&gt;\r\n        &lt;form method=\"post\"&gt;\r\n            &lt;div class=\"form-group mb-2\"&gt;\r\n                &lt;label asp-for=\"@Model.Shoe.Name\" class=\"control-label\"&gt;&lt;\/label&gt;\r\n                &lt;input asp-for=\"@Model.Shoe.Name\" class=\"form-control\" \/&gt;\r\n                &lt;span asp-validation-for=\"@Model.Shoe.Name\" class=\"text-danger\"&gt;&lt;\/span&gt;\r\n            &lt;\/div&gt;\r\n            &lt;div class=\"form-group mb-2\"&gt;\r\n                &lt;label asp-for=\"@Model.Shoe.Brand\" class=\"control-label\"&gt;&lt;\/label&gt;\r\n                &lt;input asp-for=\"@Model.Shoe.Brand\" class=\"form-control\" \/&gt;\r\n                &lt;span asp-validation-for=\"@Model.Shoe.Brand\" class=\"text-danger\"&gt;&lt;\/span&gt;\r\n            &lt;\/div&gt;\r\n            &lt;div class=\"form-group mb-2\"&gt;\r\n                &lt;label asp-for=\"@Model.Shoe.Price\" class=\"control-label\"&gt;&lt;\/label&gt;\r\n                &lt;div\u00a0class=\"input-group\"&gt; \r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div\u00a0class=\"input-group-prepend\"&gt; \r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;span\u00a0class=\"input-group-text\"&gt;\u00a3&lt;\/span&gt; \r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;input\u00a0asp-for=\"@Model.Shoe.Price\"\u00a0class=\"form-control\"\u00a0\/&gt; \r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt;\r\n                &lt;span asp-validation-for=\"@Model.Shoe.Price\" class=\"text-danger\"&gt;&lt;\/span&gt;\r\n            &lt;\/div&gt;\r\n            &lt;div class=\"form-group\"&gt;\r\n                &lt;input type=\"submit\" value=\"Create\" class=\"btn btn-primary\" \/&gt;\r\n            &lt;\/div&gt;\r\n        &lt;\/form&gt;\r\n    &lt;\/div&gt;\r\n&lt;\/div&gt;<\/pre>\n<p>Here we create a very simple form for creating shoes. In our code-behind, we create the shoe when submitting our form:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public class CreateModel : PageModel\r\n{\r\n    private readonly IFirestoreService _firestoreService;\r\n\r\n    [BindProperty]\r\n    public ShoeDto Shoe { get; set; }\r\n\r\n    public CreateModel(IFirestoreService firestoreService)\r\n    {\r\n        _firestoreService = firestoreService;\r\n    }\r\n\r\n   public async Task&lt;IActionResult&gt; OnPostAsync()\r\n   {\r\n       await _firestoreService.Add(new Shoe\r\n       {\r\n            Name = Shoe.Name,\r\n            Brand = Shoe.Brand,\r\n            Price = Shoe.Price\r\n       });\r\n\r\n       return RedirectToPage(\"Index\");\r\n   }\r\n}<\/pre>\n<p>In the <code>OnPostAsync()<\/code> method, we simply call the <code>Add()<\/code> method of our <code>FirestoreService<\/code>, and then redirect to the Index page.<\/p>\n<p>We use a <a href=\"https:\/\/code-maze.com\/difference-dto-poco\/\" target=\"_blank\" rel=\"noopener\">DTO<\/a> as our <code>BindProperty<\/code>, defining some attributes on the properties:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public class ShoeDto\r\n{\r\n    [Required]\r\n    public required string Name { get; set;}\r\n\r\n    [Required]\r\n    public required string Brand { get; set; }\r\n\r\n    [Required]\r\n    public required decimal Price { get; set; }\r\n}<\/pre>\n<p>Before we test this out, we need to enable the Firestore API for our project. To do so, let&#8217;s navigate to the Firebase console and select the Firestore Database service:<\/p>\n<p><a href=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/06\/firestore-database.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-90199\" src=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/06\/firestore-database.png\" alt=\"firestore database\" width=\"232\" height=\"217\" \/><\/a><\/p>\n<p>Next, we create a new database:<\/p>\n<p><a href=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/06\/firestore-create-database-2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-90200\" src=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/06\/firestore-create-database-2.png\" alt=\"firestore create database \" width=\"429\" height=\"231\" srcset=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/06\/firestore-create-database-2.png 429w, https:\/\/code-maze.com\/wp-content\/uploads\/2023\/06\/firestore-create-database-2-300x162.png 300w\" sizes=\"auto, (max-width: 429px) 100vw, 429px\" \/><\/a><\/p>\n<p>We&#8217;ll choose\u00a0<strong>Start in Test Mode<\/strong> for the rules configuration, and choose a suitable location. Test Mode is fine for our purposes, but in production environments, we&#8217;d strongly recommend <strong>Production Mode<\/strong>.<\/p>\n<p>Now we&#8217;re ready to add some shoes! Running our application, let&#8217;s navigate to <code>\/firestore\/create<\/code> and create a new shoe:<\/p>\n<p><a href=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/06\/firestore-create-shoe-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-90201\" src=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/06\/firestore-create-shoe-1.png\" alt=\"firestore create element\" width=\"224\" height=\"284\" \/><\/a><\/p>\n<p>This will create a new document in Firestore, and redirect us to <code>\/firestore\/index<\/code> to confirm this has been created:<\/p>\n<p><a href=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/06\/firestore-shoe-list.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-90202 size-full\" src=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/06\/firestore-shoe-list.png\" alt=\"firebase firestore element list\" width=\"663\" height=\"164\" srcset=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/06\/firestore-shoe-list.png 663w, https:\/\/code-maze.com\/wp-content\/uploads\/2023\/06\/firestore-shoe-list-300x74.png 300w\" sizes=\"auto, (max-width: 663px) 100vw, 663px\" \/><\/a><\/p>\n<p>Notice that we have an auto-generated Id for the shoe, which Firestore created for us.<\/p>\n<h2>Firebase Cloud Storage<\/h2>\n<p>So far we&#8217;ve explored the Firestore database service. Now, let&#8217;s take a look at another storage service, Firebase <a href=\"https:\/\/firebase.google.com\/docs\/storage\" target=\"_blank\" rel=\"nofollow noopener\">Cloud Storage<\/a>. <strong>This allows us to store unstructured blob data, such as images and files.<\/strong> Let&#8217;s use it to store images of the shoes we save to Firestore.<\/p>\n<p>We&#8217;ll start by adding another NuGet package:<\/p>\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"powershell\">Install-Package Google.Cloud.Storage.V1<\/code><\/p>\n<p>As we did with Firestore, we need to set up Cloud Storage in the Firebase console. Navigate to <strong>Storage<\/strong> from the menu:<\/p>\n<p><a href=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/06\/cloud-storage-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-90203\" src=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/06\/cloud-storage-1.png\" alt=\"firebase cloud storage\" width=\"228\" height=\"237\" \/><\/a><\/p>\n<p>And click\u00a0<strong>Get Started<\/strong>. Once again, we&#8217;ll choose the\u00a0<strong>Start in Test Mode<\/strong> option, and choose a suitable location.<\/p>\n<p>Now it&#8217;s time to create a new service to interact with Cloud Storage:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public class FirebaseStorageService : IFirebaseStorageService\r\n{\r\n    private readonly StorageClient _storageClient;\r\n    private const string BucketName = \"&lt;BUCKET_NAME&gt;\";\r\n\r\n    public FirebaseStorageService(StorageClient storageClient)\r\n    {\r\n        _storageClient = storageClient;\r\n    }\r\n\r\n    public async Task&lt;Uri&gt; UploadFile(string name, IFormFile file)\r\n    {\r\n        var randomGuid = Guid.NewGuid();\r\n\r\n        using var stream = new MemoryStream();\r\n        await file.CopyToAsync(stream);\r\n\r\n        var blob = await _storageClient.UploadObjectAsync(BucketName, \r\n            $\"{name}-{randomGuid}\", file.ContentType, stream);\r\n        var photoUri = new Uri(blob.MediaLink);\r\n\r\n        return photoUri;\r\n    }\r\n}<\/pre>\n<p>To start, we define some private fields. First, we have an instance of <code>StorageClient<\/code> which is the class for interacting with Cloud Storage, that we&#8217;ll inject into our constructor.\u00a0<\/p>\n<p>Secondly, we have <code>BucketName<\/code> which is the default bucket that Cloud Storage creates for us. Buckets are containers for files, which can contain subdirectories. By default, the bucket name is a concatenation of our project name, along with <code>appspot.com<\/code>, so for example <code>codemaze-firebase.appspot.com<\/code>.<\/p>\n<p>We define a single method, <code>UploadFile()<\/code> which takes two parameters, <code>name<\/code> and <code>file<\/code>. To avoid naming collisions, we generate a random GUID with the <code>NewGuid()<\/code> method.\u00a0<\/p>\n<p>Then, we read our <code>IFormFile<\/code> content into a <a href=\"https:\/\/code-maze.com\/csharp-memorystream\/\" target=\"_blank\" rel=\"noopener\">MemoryStream<\/a> with the <code>CopyToAsync()<\/code> method. Now we can upload the image to our bucket using the <code>UploadObjectAsync()<\/code> method.<\/p>\n<p>Finally, we want to return the link to our newly uploaded image so we can display it, which we do by using the <code>MediaLink<\/code> property.<\/p>\n<p>Next, we need to register the service in the <code>Program<\/code> class:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-highlight=\"5\">var builder = WebApplication.CreateBuilder(args);\r\n\r\n\/\/ code removed for brevity\r\n\r\nbuilder.Services.AddSingleton&lt;IFirebaseStorageService&gt;(s =&gt; new FirebaseStorageService(StorageClient.Create()));\r\n\r\n\/\/ code removed for brevity\r\n\r\nvar app = builder.Build();<\/pre>\n<p>Here, we register a singleton instance of our service, using the <code>Create()<\/code> method to create a new <code>StorageClient<\/code> instance.<\/p>\n<p>With the logic for uploading files to Cloud Storage implemented, let&#8217;s add the ability to upload photos when creating a new shoe.<\/p>\n<h3>Upload Images to Firebase Cloud Storage<\/h3>\n<p>First, in our <code>ShoeDto<\/code> class, we&#8217;ll add a new property:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-highlight=\"12-13\">public class ShoeDto\r\n{\r\n    [Required]\r\n    public required string Name { get; set;}\r\n\r\n    [Required]\r\n    public required string Brand { get; set; }\r\n\r\n    [Required]\r\n    public required decimal Price { get; set; }\r\n\r\n    [Required]\r\n    public required IFormFile Image { get; set; }\r\n}<\/pre>\n<p>Next, let&#8217;s add the functionality to our shoe creation form:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-highlight=\"4,9,12,17,23\">public class CreateModel : PageModel\r\n{\r\n    private readonly IFirestoreService _firestoreService;\r\n    private readonly IFirebaseStorageService _storageService;\r\n\r\n    [BindProperty]\r\n    public ShoeDto Shoe { get; set; }\r\n\r\n    public CreateModel(IFirestoreService firestoreService, IFirebaseStorageService storageService)\r\n    {\r\n        _firestoreService = firestoreService;\r\n        _storageService = storageService;\r\n    }\r\n\r\n    public async Task&lt;IActionResult&gt; OnPostAsync()\r\n    {\r\n        var photoUri = await _storageService.UploadFile(Shoe.Name, Shoe.Image);\r\n        await _firestoreService.Add(new Shoe\r\n        {\r\n            Name = Shoe.Name,\r\n            Brand = Shoe.Brand,\r\n            Price = Shoe.Price,\r\n            ImageUri = photoUri,\r\n        });\r\n\r\n        return RedirectToPage(\"Index\");\r\n    }\r\n}<\/pre>\n<p>Here, we inject our <code>IFirebaseStorageService<\/code> interface into our class constructor. In the <code>OnPostAsync()<\/code> method, we start by calling the <code>UploadFile()<\/code> method, retrieving the link to our newly created image. We use this when creating our shoes in Firestore.<\/p>\n<p>Also, we need to update our <code>FirestoreService<\/code> to set and retrieve the <code>ImageUri<\/code> property from our document:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-highlight=\"13,25\">public class FirestoreService : IFirestoreService\r\n{\r\n    \/\/ code removed for brevity\r\n\r\n    private static Shoe ConvertDocumentToModel(ShoeDocument shoeDocument)\r\n    {\r\n        return new Shoe\r\n        {\r\n            Id = shoeDocument.Id,\r\n            Name = shoeDocument.Name,\r\n            Brand = shoeDocument.Brand,\r\n            Price = decimal.Parse(shoeDocument.Price),\r\n            ImageUri = new Uri(shoeDocument.ImageUri)\r\n        };\r\n    }\r\n\r\n    private static ShoeDocument ConvertModelToDocument(Shoe shoe)\r\n    {\r\n        return new ShoeDocument\r\n        {\r\n            Id = shoe.Id,\r\n            Name = shoe.Name,\r\n            Brand = shoe.Brand,\r\n            Price = shoe.Price.ToString(),\r\n            ImageUri = shoe.ImageUri.ToString()\r\n        };\r\n    }\r\n}<\/pre>\n<p>Back on our shoe list page, we can add a new column to display our image:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"html\">&lt;td&gt;\r\n    &lt;img src=\"@shoe.ImageUri\" alt=\"shoe-image\"&gt;\r\n&lt;\/td&gt;<\/pre>\n<p>Before testing this out, we need to allow anonymous access to our bucket so unauthenticated users can render our image. To do this, we need to navigate to the <a href=\"https:\/\/console.cloud.google.com\/storage\" target=\"_blank\" rel=\"nofollow noopener\">Google Cloud Console<\/a>\u00a0and locate our bucket:<\/p>\n<p><a href=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/06\/gcp-console-buckets.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-90204\" src=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/06\/gcp-console-buckets.png\" alt=\"gcp console buckets\" width=\"369\" height=\"268\" srcset=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/06\/gcp-console-buckets.png 369w, https:\/\/code-maze.com\/wp-content\/uploads\/2023\/06\/gcp-console-buckets-300x218.png 300w\" sizes=\"auto, (max-width: 369px) 100vw, 369px\" \/><\/a><\/p>\n<p>Navigating into our bucket, we navigate to the\u00a0<strong>Permissions<\/strong> tab and click<strong> Grant Access<\/strong>:<\/p>\n<p><a href=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/06\/bucket-permissions.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-90205\" src=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/06\/bucket-permissions.png\" alt=\"bucket permissions\" width=\"488\" height=\"510\" srcset=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/06\/bucket-permissions.png 488w, https:\/\/code-maze.com\/wp-content\/uploads\/2023\/06\/bucket-permissions-287x300.png 287w\" sizes=\"auto, (max-width: 488px) 100vw, 488px\" \/><\/a><\/p>\n<p>Now, we all the <strong>allUsers<\/strong> principal, and assign the\u00a0<strong>Storage Object Viewer<\/strong> role:<\/p>\n<p><a href=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/06\/bucket-anonymous-access.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-90206\" src=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/06\/bucket-anonymous-access.png\" alt=\"bucket anonymous access\" width=\"255\" height=\"439\" srcset=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/06\/bucket-anonymous-access.png 255w, https:\/\/code-maze.com\/wp-content\/uploads\/2023\/06\/bucket-anonymous-access-174x300.png 174w\" sizes=\"auto, (max-width: 255px) 100vw, 255px\" \/><\/a><\/p>\n<p>Once saved, we can test out our new functionality. Navigating to <code>\/firestore\/create<\/code> we have the ability to add a shoe with an image.<\/p>\n<p>When the shoe document is successfully created, we are redirected to the <code>\/firestore\/index<\/code> page, where we see our new entry along with a photo, thus demonstrating we&#8217;ve successfully saved our image to our Cloud storage bucket, saving the URL to display it in our Firestore document.<\/p>\n<h2>Conclusion<\/h2>\n<p>In this article, we covered just a few of the many services Firebase offers us. We started by looking at the high-performance NoSQL database, Firestore. Next, we explored another storage option, Cloud Storage, which allows us to store unstructured blob data such as images.<\/p>\n<p>There is much more we can do with Firebase, so let us know in the comments if there&#8217;s a specific feature you&#8217;d like to see us cover.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When designing and building applications, often we find ourselves needing various third-party services, such as databases, push notifications, hosting, authentication, and many other complex features. Firebase, built by Google, is an all-in-one application development platform that provides all this functionality and more, giving us an easy-to-use platform to develop and scale our applications. Let&#8217;s start [&hellip;]<\/p>\n","protected":false},"author":39,"featured_media":62187,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"","_et_pb_old_content":"","_et_gb_content_width":"","footnotes":""},"categories":[2081],"tags":[10,79,1529,556,1825,1827,1826,682],"class_list":["post-90192","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-client-library","tag-net","tag-asp-net-core","tag-client-library","tag-database","tag-firebase","tag-firebase-cloud","tag-firestore","tag-nosql","et-has-post-format-content","et_post_format-et-post-format-standard"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v24.7 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Introduction to Firebase in .NET - Code Maze<\/title>\n<meta name=\"description\" content=\"In this article, we introduce the Firebase application development platform from Google and how to interact with it using the .NET libraries.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/code-maze.com\/dotnet-firebase\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Introduction to Firebase in .NET - Code Maze\" \/>\n<meta property=\"og:description\" content=\"In this article, we introduce the Firebase application development platform from Google and how to interact with it using the .NET libraries.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/code-maze.com\/dotnet-firebase\/\" \/>\n<meta property=\"og:site_name\" content=\"Code Maze\" \/>\n<meta property=\"article:published_time\" content=\"2023-06-12T06:00:54+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-01-31T14:32:52+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-aspnetcore.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1100\" \/>\n\t<meta property=\"og:image:height\" content=\"620\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Phil Broderick\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@CodeMazeBlog\" \/>\n<meta name=\"twitter:site\" content=\"@CodeMazeBlog\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Phil Broderick\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"14 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":[\"Article\",\"BlogPosting\"],\"@id\":\"https:\/\/code-maze.com\/dotnet-firebase\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/code-maze.com\/dotnet-firebase\/\"},\"author\":{\"name\":\"Phil Broderick\",\"@id\":\"https:\/\/code-maze.com\/#\/schema\/person\/77436f727e1038cfd00e47dc22f07158\"},\"headline\":\"Introduction to Firebase in .NET\",\"datePublished\":\"2023-06-12T06:00:54+00:00\",\"dateModified\":\"2024-01-31T14:32:52+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/code-maze.com\/dotnet-firebase\/\"},\"wordCount\":1816,\"commentCount\":2,\"publisher\":{\"@id\":\"https:\/\/code-maze.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/code-maze.com\/dotnet-firebase\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-aspnetcore.png\",\"keywords\":[\".NET\",\"asp.net core\",\"Client Library\",\"database\",\"Firebase\",\"Firebase Cloud\",\"Firestore\",\"NoSQL\"],\"articleSection\":[\"Client Library\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/code-maze.com\/dotnet-firebase\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/code-maze.com\/dotnet-firebase\/\",\"url\":\"https:\/\/code-maze.com\/dotnet-firebase\/\",\"name\":\"Introduction to Firebase in .NET - Code Maze\",\"isPartOf\":{\"@id\":\"https:\/\/code-maze.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/code-maze.com\/dotnet-firebase\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/code-maze.com\/dotnet-firebase\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-aspnetcore.png\",\"datePublished\":\"2023-06-12T06:00:54+00:00\",\"dateModified\":\"2024-01-31T14:32:52+00:00\",\"description\":\"In this article, we introduce the Firebase application development platform from Google and how to interact with it using the .NET libraries.\",\"breadcrumb\":{\"@id\":\"https:\/\/code-maze.com\/dotnet-firebase\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/code-maze.com\/dotnet-firebase\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/code-maze.com\/dotnet-firebase\/#primaryimage\",\"url\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-aspnetcore.png\",\"contentUrl\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-aspnetcore.png\",\"width\":1100,\"height\":620,\"caption\":\"ASP.NET Core\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/code-maze.com\/dotnet-firebase\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/code-maze.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Introduction to Firebase in .NET\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/code-maze.com\/#website\",\"url\":\"https:\/\/code-maze.com\/\",\"name\":\"Code Maze\",\"description\":\"Learn. Code. Succeed.\",\"publisher\":{\"@id\":\"https:\/\/code-maze.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/code-maze.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/code-maze.com\/#organization\",\"name\":\"Code Maze\",\"url\":\"https:\/\/code-maze.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/code-maze.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez.png\",\"contentUrl\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez.png\",\"width\":3511,\"height\":3510,\"caption\":\"Code Maze\"},\"image\":{\"@id\":\"https:\/\/code-maze.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/x.com\/CodeMazeBlog\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/code-maze.com\/#\/schema\/person\/77436f727e1038cfd00e47dc22f07158\",\"name\":\"Phil Broderick\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/code-maze.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/03\/phil-300x-300x-150x150.png\",\"contentUrl\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/03\/phil-300x-300x-150x150.png\",\"caption\":\"Phil Broderick\"},\"description\":\"A software developer based in the UK specializing in modernizing legacy systems and building cloud-native applications. Phil loves to gain knowledge from those around him and share his own by co-running an Azure-focused Meetup group and regularly giving talks and demos. When not exploring new Cloud technologies, Phil is an avid runner and more recently cyclist, hoping to dive into the world of Triathlons in the near future.\",\"sameAs\":[\"https:\/\/www.linkedin.com\/in\/phil-broderick\"],\"url\":\"https:\/\/code-maze.com\/author\/philbroderick\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Introduction to Firebase in .NET - Code Maze","description":"In this article, we introduce the Firebase application development platform from Google and how to interact with it using the .NET libraries.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/code-maze.com\/dotnet-firebase\/","og_locale":"en_US","og_type":"article","og_title":"Introduction to Firebase in .NET - Code Maze","og_description":"In this article, we introduce the Firebase application development platform from Google and how to interact with it using the .NET libraries.","og_url":"https:\/\/code-maze.com\/dotnet-firebase\/","og_site_name":"Code Maze","article_published_time":"2023-06-12T06:00:54+00:00","article_modified_time":"2024-01-31T14:32:52+00:00","og_image":[{"width":1100,"height":620,"url":"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-aspnetcore.png","type":"image\/png"}],"author":"Phil Broderick","twitter_card":"summary_large_image","twitter_creator":"@CodeMazeBlog","twitter_site":"@CodeMazeBlog","twitter_misc":{"Written by":"Phil Broderick","Est. reading time":"14 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":["Article","BlogPosting"],"@id":"https:\/\/code-maze.com\/dotnet-firebase\/#article","isPartOf":{"@id":"https:\/\/code-maze.com\/dotnet-firebase\/"},"author":{"name":"Phil Broderick","@id":"https:\/\/code-maze.com\/#\/schema\/person\/77436f727e1038cfd00e47dc22f07158"},"headline":"Introduction to Firebase in .NET","datePublished":"2023-06-12T06:00:54+00:00","dateModified":"2024-01-31T14:32:52+00:00","mainEntityOfPage":{"@id":"https:\/\/code-maze.com\/dotnet-firebase\/"},"wordCount":1816,"commentCount":2,"publisher":{"@id":"https:\/\/code-maze.com\/#organization"},"image":{"@id":"https:\/\/code-maze.com\/dotnet-firebase\/#primaryimage"},"thumbnailUrl":"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-aspnetcore.png","keywords":[".NET","asp.net core","Client Library","database","Firebase","Firebase Cloud","Firestore","NoSQL"],"articleSection":["Client Library"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/code-maze.com\/dotnet-firebase\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/code-maze.com\/dotnet-firebase\/","url":"https:\/\/code-maze.com\/dotnet-firebase\/","name":"Introduction to Firebase in .NET - Code Maze","isPartOf":{"@id":"https:\/\/code-maze.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/code-maze.com\/dotnet-firebase\/#primaryimage"},"image":{"@id":"https:\/\/code-maze.com\/dotnet-firebase\/#primaryimage"},"thumbnailUrl":"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-aspnetcore.png","datePublished":"2023-06-12T06:00:54+00:00","dateModified":"2024-01-31T14:32:52+00:00","description":"In this article, we introduce the Firebase application development platform from Google and how to interact with it using the .NET libraries.","breadcrumb":{"@id":"https:\/\/code-maze.com\/dotnet-firebase\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/code-maze.com\/dotnet-firebase\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/code-maze.com\/dotnet-firebase\/#primaryimage","url":"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-aspnetcore.png","contentUrl":"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-aspnetcore.png","width":1100,"height":620,"caption":"ASP.NET Core"},{"@type":"BreadcrumbList","@id":"https:\/\/code-maze.com\/dotnet-firebase\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/code-maze.com\/"},{"@type":"ListItem","position":2,"name":"Introduction to Firebase in .NET"}]},{"@type":"WebSite","@id":"https:\/\/code-maze.com\/#website","url":"https:\/\/code-maze.com\/","name":"Code Maze","description":"Learn. Code. Succeed.","publisher":{"@id":"https:\/\/code-maze.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/code-maze.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/code-maze.com\/#organization","name":"Code Maze","url":"https:\/\/code-maze.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/code-maze.com\/#\/schema\/logo\/image\/","url":"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez.png","contentUrl":"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez.png","width":3511,"height":3510,"caption":"Code Maze"},"image":{"@id":"https:\/\/code-maze.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/CodeMazeBlog"]},{"@type":"Person","@id":"https:\/\/code-maze.com\/#\/schema\/person\/77436f727e1038cfd00e47dc22f07158","name":"Phil Broderick","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/code-maze.com\/#\/schema\/person\/image\/","url":"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/03\/phil-300x-300x-150x150.png","contentUrl":"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/03\/phil-300x-300x-150x150.png","caption":"Phil Broderick"},"description":"A software developer based in the UK specializing in modernizing legacy systems and building cloud-native applications. Phil loves to gain knowledge from those around him and share his own by co-running an Azure-focused Meetup group and regularly giving talks and demos. When not exploring new Cloud technologies, Phil is an avid runner and more recently cyclist, hoping to dive into the world of Triathlons in the near future.","sameAs":["https:\/\/www.linkedin.com\/in\/phil-broderick"],"url":"https:\/\/code-maze.com\/author\/philbroderick\/"}]}},"_links":{"self":[{"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/posts\/90192","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/users\/39"}],"replies":[{"embeddable":true,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/comments?post=90192"}],"version-history":[{"count":8,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/posts\/90192\/revisions"}],"predecessor-version":[{"id":91658,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/posts\/90192\/revisions\/91658"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/media\/62187"}],"wp:attachment":[{"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/media?parent=90192"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/categories?post=90192"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/tags?post=90192"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}