<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Gareth Brown</title>
    <description>The latest articles on DEV Community by Gareth Brown (@garethbrown82).</description>
    <link>https://dev.to/garethbrown82</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F137182%2F4a632d9b-17f8-44ab-8ad5-3b529b5a5b35.jpeg</url>
      <title>DEV Community: Gareth Brown</title>
      <link>https://dev.to/garethbrown82</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/garethbrown82"/>
    <language>en</language>
    <item>
      <title>Building a notes API with Firebase Functions</title>
      <dc:creator>Gareth Brown</dc:creator>
      <pubDate>Thu, 08 Oct 2020 08:54:01 +0000</pubDate>
      <link>https://dev.to/garethbrown82/building-a-notes-api-with-firebase-functions-51k4</link>
      <guid>https://dev.to/garethbrown82/building-a-notes-api-with-firebase-functions-51k4</guid>
      <description>&lt;p&gt;I’ve been a big fan of Firebase for a while and have now used it in a number of project. I’ve even put together a &lt;a href="https://www.manning.com/livevideo/building-web-applications-with-firebase"&gt;video course about it with Manning&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However it’s only recently that I’ve started to use Firebase Cloud Functions. A way to easily develop and deploy cloud functions on the Firebase platform with seemless integration into other Firebase services such as Firestore and the Firebase Local Emulator Suite.&lt;/p&gt;

&lt;p&gt;In this tutorial blog post I want to create an API endpoint using Cloud Funcitons where we can create and get notes from Firestore. We’ll also develop this functionality using the Firebase Local Emulator Suite.&lt;/p&gt;

&lt;p&gt;I’m going to assume some basic knowledge of Firebase here but with some reference to Firebase docs you’ll still be able to follow this post. I’m just not going to go into details about all the Firebase concepts covered.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create a Firebase Project
&lt;/h3&gt;

&lt;p&gt;Add a new project from the &lt;a href="https://console.firebase.google.com/"&gt;Firebase Console&lt;/a&gt; and give it a name. I’ve call mine Notes Editor.&lt;/p&gt;

&lt;p&gt;&lt;a href="///static/7c1ec87df0d417fac7c2f8fc4ddb53ad/8710b/project_name.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Eol17j0M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://garethbrown.dev/static/7c1ec87df0d417fac7c2f8fc4ddb53ad/8710b/project_name.png" alt="Project name"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There’ll be a question about Google Analytics, whether you decide to add it or not is up to you. Then click to create your project.&lt;/p&gt;

&lt;p&gt;Now that the project is setup we won’t need to refer to the Firebase console very much for the rest of this post.&lt;/p&gt;

&lt;h3&gt;
  
  
  Node and Firebase CLI
&lt;/h3&gt;

&lt;p&gt;You will need to make sure Node is installed and also the &lt;a href="https://firebase.google.com/docs/cli?#setup_update_cli"&gt;Firebase CLI&lt;/a&gt;. If node is aready installed you can install the Firebase CLI with &lt;code&gt;npm install -g firebase-tools&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Once Firebase CLI is installed make sure you are logged in using &lt;code&gt;firebase login&lt;/code&gt;. This is so the CLI knows who Firebase account you actually want the CLI to interact with.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create the project
&lt;/h3&gt;

&lt;p&gt;Start by creating a directory to house your project with &lt;code&gt;mkdir notes-editor&lt;/code&gt; then navigate to it with &lt;code&gt;cd notes-editor&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now that we’re in the project directories root we can initialise this as a Firebase project. Use the Firebase CLI to do this by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;firebase init functions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’ll be asked a few questions. First we need to specify which Firebase project we want to associate with the project we’re initialising. Select the option to &lt;strong&gt;Use an existing project&lt;/strong&gt; and then choose the project you’ve just created in the Firebase console named Notes Editor. You’ll just see the Project ID which for me reads as &lt;code&gt;notes-editor-c330b&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Next you’ll be asked what language you want to use, either JavaScript or TypeScript. I’m going to keep it simple and select JavaScript. I’ve also selected to use ESLint and specified that I &lt;strong&gt;want to install dependencies with npm now&lt;/strong&gt;. Otherwise you’ll have to install them later with &lt;code&gt;npm install&lt;/code&gt; anyway.&lt;/p&gt;

&lt;p&gt;Now we wait while Firebase CLI does its thing and NPM dependencies get installed. Once completed you should see a message indicating that Firebase initilization is complete.&lt;/p&gt;

&lt;p&gt;&lt;a href="///static/9653f9d0637ce1c7f8c45b040115024e/e66bf/initilization_complete.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--W7L04BIh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://garethbrown.dev/static/9653f9d0637ce1c7f8c45b040115024e/e66bf/initilization_complete.png" alt="Firebase initilization complete"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Spend a few minutes having a look at the files and directories that have been created. I won’t go over the details of what each do but you should note that you now have a &lt;code&gt;/functions&lt;/code&gt; folder. This is where all your cloud function code is going to live.&lt;/p&gt;

&lt;p&gt;I do want to draw your attention to one detail in the &lt;code&gt;package.json&lt;/code&gt; file inside the functions directory. You will see that the node version is set to 10.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"engines": {
  "node": "10"
},
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the recommended version and will all work fine, unless you want to deploy your functions to Firebase using the free Spark plan. The free Spark plan only support Node 8, which was deprecated on June 8th 2020. Firebase will halt execution of these function after March 15, 2021. It’s hard to know what will happen regarding running Cloud Functions on Firebase using the free Spark plan but you might need to bite the bullet and upgrade to the pay as you go Blaze plan.&lt;/p&gt;

&lt;p&gt;We’ll leave this as Node 10 for now as we’re only going to be running this locally using the Firebase Local Emulator Suite.&lt;/p&gt;

&lt;h3&gt;
  
  
  Running functions locally
&lt;/h3&gt;

&lt;p&gt;If you have a look at &lt;code&gt;/functions/index.js&lt;/code&gt; you’ll see that there’s already a &lt;code&gt;helloWorld&lt;/code&gt; function for us to use that’s commented out. Uncomment the function so we can run it and see what happens.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const functions = require('firebase-functions');

// Create and Deploy Your First Cloud Functions
// https://firebase.google.com/docs/functions/write-firebase-functions

exports.helloWorld = functions.https.onRequest((request, response) =&amp;gt; {
  functions.logger.info("Hello logs!", {structuredData: true});
  response.send("Hello from Firebase!");
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can now try this by running Emulator Suite using the Firebase CLI from the root of our project directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;firebase emulators:start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see the URL of the Emulator Suite dashboard in the console. Mine is running at &lt;a href="http://localhost:4000"&gt;http://localhost:4000&lt;/a&gt; so I’ll open this in my browswer.&lt;/p&gt;

&lt;p&gt;&lt;a href="///static/99614a3b94b5dc480dacb04541b10c5f/7de01/emulator_console.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9uFMgSLV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://garethbrown.dev/static/99614a3b94b5dc480dacb04541b10c5f/fcda8/emulator_console.png" alt="Emulator Suite URL"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once it’s running navigate to the URL and you should be on the Emulator’s overview page.&lt;/p&gt;

&lt;p&gt;&lt;a href="///static/e9403026feeb13fd06b57b4b2314f375/75a80/emulator_dashboard.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--neaoVrWF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://garethbrown.dev/static/e9403026feeb13fd06b57b4b2314f375/fcda8/emulator_dashboard.png" alt="Emulator Suite overview"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Navigate to the Logs tab, this will give you the output you need to find out where your functions are running and the URL to send your http request to. You can see below that the hello world function for me is running at &lt;a href="http://localhost:5001/notes-editor-c330b/us-central1/helloWorld"&gt;http://localhost:5001/notes-editor-c330b/us-central1/helloWorld&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="///static/5ce77f9a847fcb7623f305bf3d124f85/75a80/emulator_logs.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mGnV-G0y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://garethbrown.dev/static/5ce77f9a847fcb7623f305bf3d124f85/fcda8/emulator_logs.png" alt="Emulator logs"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As this is a get request you can just paste the URL in your browser and you’ll see the respone.&lt;/p&gt;

&lt;p&gt;&lt;a href="///static/da26c006955500cceee0d4d320f6e78e/1843f/helloworld_response.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yrb8JHCU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://garethbrown.dev/static/da26c006955500cceee0d4d320f6e78e/fcda8/helloworld_response.png" alt="Hello world response"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Woo hoo! Looks like that worked perfectly :)&lt;/p&gt;

&lt;h3&gt;
  
  
  Firestore Setup
&lt;/h3&gt;

&lt;p&gt;We’re going to start with writing a get request, except that we have no data to get! So initially we’re just going to manually add data to the database that we can retrieve. Later we’ll add this using another function.&lt;/p&gt;

&lt;p&gt;We don’t have Firestore initialised yet so let’s do that now. Stop the Firebase emulator if it is running and in the root of your project run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;firebase init firestore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’ll most likely see the following output indicating that you need to setup Firestore in your Firebase project.&lt;/p&gt;

&lt;p&gt;&lt;a href="///static/75488db9e250b30a495d2b9cc569f273/dcccd/firestore_init_output.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--678K-hHa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://garethbrown.dev/static/75488db9e250b30a495d2b9cc569f273/fcda8/firestore_init_output.png" alt="Firestore initialise output"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fortunately is tells you the URL you can paste into your browser to set up Firestore. The link for my project is &lt;a href="https://console.firebase.google.com/project/notes-editor-c330b/firestore"&gt;https://console.firebase.google.com/project/notes-editor-c330b/firestore&lt;/a&gt;. Yours will be similar. Once you paste this link into the browser you will land on the the Firestore tab of you Firebase project. Click the “Create database” button circled below in blue.&lt;/p&gt;

&lt;p&gt;&lt;a href="///static/b1ca6275865a0a0f3072a04fd41f6235/75a80/setup_firestore.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3zNkwXum--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://garethbrown.dev/static/b1ca6275865a0a0f3072a04fd41f6235/fcda8/setup_firestore.png" alt="Create Firestore database"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You’ll be asked to set your initial security rules, for this sake of simplicity just set this to test mode. You can find out more about &lt;a href="https://firebase.google.com/docs/firestore/security/get-started"&gt;Firestore security rules&lt;/a&gt; but all you need to know here is that if you put this project live then everyone will have read and write access to your database so don’t do that until you’ve got your security rules covered. I also talk about the security rules in &lt;a href="https://www.manning.com/livevideo/building-web-applications-with-firebase"&gt;my Firebase video course&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Next set the location that’s closest to you and click “Enable”.&lt;/p&gt;

&lt;p&gt;Once Firestore is setup in your project you can run &lt;code&gt;firebase init firestore&lt;/code&gt;, select all the defaults for questions about which files to use for security rules and indexes. Now that Firestore has been initialised, we will be able to access this in the Firebase emulator. Start up the emulator again with &lt;code&gt;firebase emulators:start&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Once the emulator has started navigate to the emulator dashboard in your browser and click on the Firestore tab. You should see an empty database similar to this:&lt;/p&gt;

&lt;p&gt;&lt;a href="///static/a7e4794a7ccf1dca08ca415921d411cc/4b701/firestore_empty.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eShku0YX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://garethbrown.dev/static/a7e4794a7ccf1dca08ca415921d411cc/fcda8/firestore_empty.png" alt="Empty Firestore tab"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lets manually add some data that we can retrieve with our get request…&lt;/p&gt;

&lt;p&gt;Click the “Start collection” button and create a collection with a collection ID of &lt;code&gt;notes&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="///static/10b36d6f2f31b645eef8fd65c259863d/9f933/notes_collection.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DZinYgHH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://garethbrown.dev/static/10b36d6f2f31b645eef8fd65c259863d/9f933/notes_collection.png" alt="Notes collection"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click “Next” and you’ll be give the option to add fields to the &lt;a href="https://firebase.google.com/docs/firestore/data-model"&gt;first document of this collection&lt;/a&gt;. Create three fields labelled “created”, “title”, and “text”. The “created” fields will be a time stamp, “title” and “text” will just be strings. Add some values to these fields, you can see how I’ve populated them below. Click “Save” once you’re done.&lt;/p&gt;

&lt;p&gt;&lt;a href="///static/34ca68713deec52739901cdc047e718d/c5bb3/notes_document.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QR1cE5S6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://garethbrown.dev/static/34ca68713deec52739901cdc047e718d/fcda8/notes_document.png" alt="Notes document"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You should now be able to see your new notes collection and document in your Firestore instance.&lt;/p&gt;

&lt;p&gt;&lt;a href="///static/9c5fe0672ced2b9ef26ab54e4c152231/b4cdf/firestore_notes_document.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Cp7gYEya--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://garethbrown.dev/static/9c5fe0672ced2b9ef26ab54e4c152231/fcda8/firestore_notes_document.png" alt="Firestore notes document"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’m going to add two more notes so I’ve got a few more, you can add some more yourself by clicking the “Add document” button in the notes collection column. Make sure your notes document have the exact same fields of &lt;code&gt;created&lt;/code&gt;, &lt;code&gt;title&lt;/code&gt; and &lt;code&gt;text&lt;/code&gt;. Once these are added we can start to write our get request function.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I’m not sure why but when I first create a new document and click save, my Firestore only shows the notes collection in a single large column. I can’t see my documents even when I click on &lt;code&gt;notes&lt;/code&gt;. This was resolved easily enough just by refreshing the browser.&lt;/p&gt;

&lt;p&gt;&lt;a href="///static/0f4cb9aa495813d7e076babf715885d9/75a80/collection_bug.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--q2xk0rev--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://garethbrown.dev/static/0f4cb9aa495813d7e076babf715885d9/fcda8/collection_bug.png" alt="Collection screen bug"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Persisting Firestore data in emulator
&lt;/h3&gt;

&lt;p&gt;Before you stop the emulator you should be aware that the data you’ve just added will not persist, so the next time you fire up the emulator it will be gone!&lt;/p&gt;

&lt;p&gt;However while the emulator is still running you can export the data to a specified directory. Let’s export the notes data to a directory named firestore_data by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;firebase emulators:export firestore_data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can now safely stop the emulator. Next time you fire up the emulator you can use the following to import the firestore data from the firestore_data directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;firebase emulators:start --import=firestore_data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can then use different data directories for different data sets if required.&lt;/p&gt;

&lt;h3&gt;
  
  
  Get request
&lt;/h3&gt;

&lt;p&gt;We’re going to use Express to handle our requests, so install this first. Make sure you’re in the &lt;code&gt;/functions&lt;/code&gt; directory as this is where we’ll manage the packages for our cloud functions. Later we may want to setup a front end to consume the endpoints, which we want to keep separate from the cloud functions.&lt;/p&gt;

&lt;p&gt;Install Express inside &lt;code&gt;/notes-editor/functions&lt;/code&gt; directory with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --save express
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now create a new file named &lt;code&gt;notes.js&lt;/code&gt; inside &lt;code&gt;/notes-editor/functions&lt;/code&gt; and add the following code:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;notes.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const functions = require('firebase-functions');
const express = require('express');
const admin = require('firebase-admin');

// Create Express app
const app = express();

// Initialize Firebase admin to access Firestore from the server
admin.initializeApp();

app.get('/', async (request, response) =&amp;gt; {
  functions.logger.info('Triggering get notes request', { structuredData: true });

  try {
    // Use admin to access a reference to the notes collection in Firestore
    const notesRef = admin.firestore().collection('notes');

    // Get all notes from the notes collection in descending order of 'created' field
    const notesCollection = await notesRef.orderBy('created', 'desc').get();

    // Add notes document data to an array
    let notes = [];
    notesCollection.forEach((note) =&amp;gt; {
      notes.push(note.data());
    });

    // return notes array as a json response
    response.json(notes);
  } catch (error) {
    // Log and return error status if things go wrong
    functions.logger.error(error);
    response.status(500).send('Internal server error');
  }
});

exports.notes = functions.https.onRequest(app);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I’ve added comments to the code to give a brief explanation of what’s happing. You can see we’ve imported Express to manage the request and also the &lt;a href="https://firebase.google.com/docs/database/admin/start"&gt;Firebase admin SDK&lt;/a&gt;, which we use to access the Firestore API by calling &lt;code&gt;admin.firestore()&lt;/code&gt;. We then get a reference to the &lt;code&gt;notes&lt;/code&gt; collection and asynchronously call the &lt;code&gt;get()&lt;/code&gt; method to return the notes. We add the note data from each document to an array and return the array in json format.&lt;/p&gt;

&lt;p&gt;Now open up the &lt;code&gt;index.js&lt;/code&gt; file which contains our ‘hello world’ function. Delete all the current code and use this file to import and export our &lt;code&gt;notes.js&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;index.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const notes = require('./notes');

exports.notes = notes.notes;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Call your function in the browser again, remember you can find the URL in the firebase emulator logs tab. When I call this get request it returns the following json data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
  {
    "created": {
      "_seconds": 1602570624,
      "_nanoseconds": 649000000
    },
    "title": "My First Note",
    "text": "This is the text of my first note."
  },
  {
    "created": {
      "_seconds": 1602571345,
      "_nanoseconds": 317000000
    },
    "title": "To do",
    "text": "Finish this tutorial."
  },
  {
    "created": {
      "_seconds": 1602571432,
      "_nanoseconds": 222000000
    },
    "title": "Exercise",
    "text": "Rock climbing on Friday."
  }
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We’ve now successfully returned the data stored in Firestore using a Firebase Cloud Function, well done! Now let’s write a function that will add a new notes to Firestore using a post request.&lt;/p&gt;

&lt;h3&gt;
  
  
  Post request
&lt;/h3&gt;

&lt;p&gt;Directly underneath our get request we’re going to create a post request to the same endpoint, which will allow us to save notes to Firestore.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.post('/', async (request, response) =&amp;gt; {
  functions.logger.info('Triggering post note request', { structuredData: true });

  // Construct the note object to add to Firestore
  const note = { 
    created: admin.firestore.Timestamp.now(),
    title: request.body.title,
    text: request.body.text, 
  }

  try {
    // Save the note to the Firestore notes collection
    await admin.firestore().collection('notes').add(note);
    response.json({ message: 'Note added successfully'});
  } catch (error) {
    // Log and return error status if things go wrong
    functions.logger.error(error);
    response.status(500).send('Internal server error');
  }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We’ve used the Firestore &lt;code&gt;Timestamp&lt;/code&gt; class to get the created time in the Firestore timestamp format. The title and text come straight from the body of the request, which will need to look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "title": "Title goes here",
    "text": "Text for your note goes here"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To try this now you won’t be able to use the browser becuase it is a get request, you’ll need to use a tool like &lt;a href="https://www.postman.com/"&gt;Postman&lt;/a&gt; or curl.&lt;/p&gt;

&lt;p&gt;The URL will be the same as your get request but you’ll need to specify in Postman that it’s a post request. My Postman setup for this request looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="///static/24cf177953625f349b23baac8a56b367/7de01/postman_request.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--n2R_5ssC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://garethbrown.dev/static/24cf177953625f349b23baac8a56b367/fcda8/postman_request.png" alt="Postman add note request"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you’ve successfully added a note your response should indicate this with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "message": "Note added successfully"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Deploying functions to live
&lt;/h3&gt;

&lt;p&gt;We’ve now create a post request to save a note to Firestore and a get request to get all our notes from Firestore. It’s time for us to deploy to live. It’s important again though to point out that we have not implemented anykind of authentication here so when it’s live anyone can add notes to your projects instance of Firestore. But for the purpose of this tutorial and learning the process we’re going to be ok with that for now.&lt;/p&gt;

&lt;p&gt;If you’re using the free Spark plan you’ll need to change the node version to 8, although as discussed earlier in this tutorial this is deprecated and will be decommissioned on 2021-03-15.&lt;/p&gt;

&lt;p&gt;In your &lt;code&gt;/functions/package.json&lt;/code&gt; file make sure node is set to version 8:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"engines": {
  "node": "8"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you try to deploy your functions on the free Spark plan with the node version set to 10 then you’ll see the following error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error: HTTP Error: 400, Billing account for project '3012########' is not found. Billing must be enabled for activation of service(s) 'cloudbuild.googleapis.com,containerregistry.googleapis.com' to proceed.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you’ve changed your node version to 8 then you can deploy your functions to live using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;firebase deploy --only functions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When I first tried this I got the following unhelpful error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error: HTTP Error: 403, Unknown Error
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is resolved by logging into your Firebase console, clicking on the ‘functions’ menu link and clicking ‘Get started’. You’ll be shown a couple of steps about how the setup Functions in your project, but we’ve already gone through these so you can ignore them.&lt;/p&gt;

&lt;p&gt;&lt;a href="///static/515240b3cef36b480443185c0b91b07e/ae694/functions_get_started.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XhFur0ZP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://garethbrown.dev/static/515240b3cef36b480443185c0b91b07e/fcda8/functions_get_started.png" alt="Firebase functions get started"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now try deploying your function again with &lt;code&gt;firebase deploy --only functions&lt;/code&gt;. Once deployed successfully you should see something like the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="///static/56ae3a8416950d2b8f6f1613da6b4146/0d0e4/functions_deployed.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kj4pktyb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://garethbrown.dev/static/56ae3a8416950d2b8f6f1613da6b4146/fcda8/functions_deployed.png" alt="Functions deployed successfully"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see I’ve highlighted the endpoint URL to access your function. You can now use this in Postman to add some notes to your live instance of Firestore. You can see your notes added to Firestore from your Firebase project console, as seen below:&lt;/p&gt;

&lt;p&gt;&lt;a href="///static/61e495672335bf48d6947a6b5aa9ca3f/ae694/firestore_console.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LPF8Cm6C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://garethbrown.dev/static/61e495672335bf48d6947a6b5aa9ca3f/fcda8/firestore_console.png" alt="Firestore project console"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ok that concludes this tutorial and should be enough to get you started using Firebase Cloud Functions. I’ve put some references below that I found very helpful and that I referenced throughout this tutorial. I recommend that you have a look.&lt;/p&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;p&gt;Here’s some links to documentations that I’ve used and reference material for this post. I’d recommend you looking at them if you want to know more about the Firebase concepts I’ve discussed in this post.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.manning.com/livevideo/building-web-applications-with-firebase"&gt;Building Web Applications with Firebase&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’ve developed this video course with Manning. The focus is on getting developers brand new to Firebase up and running quickly to build web apps using Firebase services such as Hosting, Firestore, Cloud Storage and Authentication.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://firebase.google.com/docs/functions/get-started"&gt;Get started with Cloud Functions&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the first place I would go to as a starting point for Firebase Cloud Functions and was referenced heavily for the initial setup phase of this post.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://firebase.google.com/docs/projects/learn-more"&gt;Understand Firebase Projects&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A great reference for what a Firebase project is and how it relates to projects on the Google Cloud Platform. Namely that they are the &lt;strong&gt;same thing!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://firebase.google.com/docs/cli?#setup_update_cli"&gt;Firebase CLI&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The CLI you need for all things Firebase.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://firebase.google.com/docs/firestore/security/get-started"&gt;Firestore security rules&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;An important concept to know if your going to use Firebase for a live web app. Do not put anything live without understanding this first!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://firebase.google.com/docs/firestore"&gt;Firebase Firestore&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can learn more about Firestore and how it works here.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>GitHub CLI</title>
      <dc:creator>Gareth Brown</dc:creator>
      <pubDate>Wed, 07 Oct 2020 08:26:42 +0000</pubDate>
      <link>https://dev.to/garethbrown82/github-cli-488k</link>
      <guid>https://dev.to/garethbrown82/github-cli-488k</guid>
      <description>&lt;p&gt;I’ve seen this new GitHub CLI pop up recently in articles and as I use GitHub for both projects at work and home it makes complete sense for me to check it out. Hopefully you’ll find my notes below useful for when you dive in yourself!&lt;/p&gt;

&lt;p&gt;I’m mainly following the guides from the &lt;a href="https://cli.github.com/"&gt;official GitHub CLI page&lt;/a&gt;, there also a &lt;a href="https://youtu.be/vcAIZ4axYZU"&gt;youtube intro video&lt;/a&gt; you can watch.&lt;/p&gt;

&lt;h3&gt;
  
  
  Installing GitHub CLI
&lt;/h3&gt;

&lt;p&gt;Not much to it really:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew install gh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Authenticating
&lt;/h3&gt;

&lt;p&gt;GitHub CLI needs to know who you are and which repo to connect to. You can kick that process off with the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh auth login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’ll first get asked a few questions. There are the answers I gave, but your preferences may be different.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What account do you want to log into?&lt;/strong&gt; A: GitHub.com&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How would you like to authenticate?&lt;/strong&gt; A: Paste an authentication token&lt;/p&gt;

&lt;p&gt;You’ll then be given a url where you can create a token so the GitHub CLI can access your account. &lt;a href="https://github.com/settings/tokens"&gt;https://github.com/settings/tokens&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Click “generate new token” and you’ll be asked to add a note. This note is to let you know what the token is for when you need to look at your tokens later. I’ve just added a note reading “GitHub CLI”.&lt;/p&gt;

&lt;p&gt;You’ll then need to select scopes depending on what access you want this token to have. As it’s my personal account and I want to be able to do everything possible with the GitHub CLI I’ve just selected everything.&lt;/p&gt;

&lt;p&gt;&lt;a href="///static/0ec64c3f34a7dfdd8016bd6e01337847/0abdd/github-token-selection.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--veD_LnEW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://garethbrown.dev/static/0ec64c3f34a7dfdd8016bd6e01337847/0abdd/github-token-selection.png" alt="GitHub token settings"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click the green “generate token” button down the bottom of the page.&lt;/p&gt;

&lt;p&gt;Then you’ll see your token, make sure to copy it now as once you close the tab it will be gone forever! You’ll have to then delete it and regenerate a new token.&lt;/p&gt;

&lt;p&gt;Return to the command line and paste the token into the GitHub CLI setup.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Choose default git protocol&lt;/strong&gt; A: SSH&lt;/p&gt;

&lt;p&gt;You should then see a message indicating that you have &lt;code&gt;Configured git protocol&lt;/code&gt; and who you’re logged in as.&lt;/p&gt;

&lt;h3&gt;
  
  
  CLI commands
&lt;/h3&gt;

&lt;p&gt;I’ll probably update the following section as I use this CLI tool. I’m planning on using it overtime to see how I find it. To find out more info about what the GitHub CLI can do I would recommend &lt;a href="https://cli.github.com/manual/"&gt;reading the docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creating a pull request&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Make sure you’re on the branch you want to create a pull request for and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh pr create
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will be asked a series of questions about the details of your pull request:&lt;/p&gt;

&lt;p&gt;Title? - Title of the PR&lt;/p&gt;

&lt;p&gt;Body? - Body description of the PR. This can be opened in nano by pressing ‘e’ or skipped with ‘enter’&lt;/p&gt;

&lt;p&gt;Then you’re given the option to submit your PR. Once submitted you’re given the link that will take you directly to the PR in GitHub.&lt;/p&gt;

&lt;p&gt;This will create a PR into your default branch, if you want the PR into another branch you can add the &lt;code&gt;--base&lt;/code&gt; flag. If I wanted the PR to go into my develop branch for example I could use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh pr create --base develop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that our PR exists let’s pretend that someone has reviewed it and found it to be of the highest coding standard they’ve ever seen. So it’s time to merge. This can be done directly from the CLI with either the PR number, URL or branch name.&lt;/p&gt;

&lt;p&gt;To display a list of your current PRs enter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh pr list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then once you have the number for the PR you want to merge you can do this with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh pr merge 18
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will give you a few options of how you would like to merge such as &lt;code&gt;Create a merge commit&lt;/code&gt;, &lt;code&gt;Rebase and merge&lt;/code&gt; or &lt;code&gt;Squash and merge&lt;/code&gt;. I’m going to pick the first option to create a merge commit. You’ll also be given the option to delete both the local and remote branches, which I really like becuase I’m terrible at remembering to delete branches I don’t need anymore.&lt;/p&gt;

&lt;p&gt;To run the command without having to answer these questions you can also use the flags &lt;code&gt;--merge&lt;/code&gt; and &lt;code&gt;--delete-branch&lt;/code&gt; or using the single character flags together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh pr merge 18 -md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; If you get a message indicating that &lt;strong&gt;Pull request #18 (Github CLI) can’t be merged right now; try again in a few seconds&lt;/strong&gt; then it may be because some kind of CI is still running or there’s another reason you can’t merge yet such as requiring more reviews etc…&lt;/p&gt;




</description>
    </item>
  </channel>
</rss>
