Skip to content

This Dot Blog

This Dot provides teams with technical leaders who bring deep knowledge of the web platform. We help teams set new standards, and deliver results predictably.

Newest First
Tags: Firebase
How to Deploy your Angular App and Latest Build Tools for JavaScript cover image

How to Deploy your Angular App and Latest Build Tools for JavaScript

How to Deploy your Angular App to Production with Firebase Hosting How do you deploy an Angular application? According to the Angular documentation: > To deploy your application, you have to compile it, and then host the JavaScript, CSS, and HTML on a web server. Built Angular applications are very portable and can live in any environment or served by any technology, such as Node, Java, .NET, PHP, and many others. Follow these steps: * Install Angular CLI * Setup Basic Angular Project * Create Firebase Account to Deploy Angular Application * Install the Firebase Tools using Firebase CLI * Login and Initialize Firebase project using Firebase CLI * Create Production Build * Deploy your Angular App to Firebase Hosting * Finally, it’s deployed on Firebase Server See all the detailed steps in this article: Deploy Angular 10/9 App to Production with Firebase Hosting The latest build tools for JavaScript Let's explore the latest build tools that the JavaScript ecosystem uses today. Rollup.js According to the official website: > Rollup is a module bundler for JavaScript which compiles small pieces of code into something larger and more complex, such as a library or application. Installation ` Pros of using Rollup.js The following are some of the cool features that Rollup offers to JavaScript developers: * Fast builds * It’s easy to learn and get started with, as well as publish JavaScript packages * Code-splitting * Less and easier configuration compared to Webpack * Perfect for JavaScript libraries * Plugins for better builds and customizations, along with custom plugin support * It provides a smaller bundle size and produces clean code * Provides awesome support for ES Modules Parcel According to the official website: > Parcel is a web application bundler, differentiated by its developer experience. It offers blazing fast performance utilizing multicore processing, and requires zero configuration. Installation ` Features of Parcel * Blazingly fast builds * Awesome developer experience * Zero configuration — just install and get started * Plugin support, although you don’t necessarily need plugins * Custom plugins support * Multi-core processing * Support for low-level languages like Rust and anything that compiles to WebAssembly (WASM) * Hot Module Replacement (HMR) support out of the box * Support for code-splitting out of the box * Support for low-level languages like Rust and WASM * Support for React and Typescript out of the box Snowpack > Snowpack is a lightning-fast frontend build tool, designed for the modern web. It is an alternative to heavier, more complex bundlers like webpack or Parcel in your development workflow. Snowpack leverages JavaScript's native module system (known as ESM) to avoid unnecessary work and stay fast no matter how big your project grows. Installation ` Pros of using Snowpack * O(1) build times * No bundling in production * Lightning-fast builds * Hot Module Replacement support * Out-of-the-box support for TypeScript, JSX, CSS Modules, and the like * Simple tooling * App templates for developers esbuild > An extremely fast JavaScript bundler Installation ` Features of esbuild * Extremely fast builds * Loaders for Typescript, JavaScript, and JSON * Minification * Code-splitting support(Work in Progress) * Bundling * Tree-Shaking * Support for various output formats like CJS, IIFE, and ESM * Source map generation * Transpilation of JSX and newer JS syntax down to ES6 Find more information in this article: [The top latest build tools for JavaScript ](https://blog.logrocket.com/the-top-latest-build-tools-for-javascript/)...

Going Serverless with Vue.js and Firebase Cloud Functions cover image

Going Serverless with Vue.js and Firebase Cloud Functions

Welcome to a new episode of the Fire the base of Vue.js! series. In this episode, I will integrate our Vue.js Notes Writer App with a serverless backend- specifically, the Firebase Cloud Functions. If you haven’t read the other parts of this series, I highly recommend you do so before starting here. Vue the Mirage from this angle! Storing your notes in the Cloud Firestore with Vue.js Firebase for user authentication in Vue.js To follow up on the demo part of this article, you can use this GitHub source code repo as a starting point. Firebase Cloud Functions, the concept Cloud Functions are part of the Google Cloud Platform. You use them to write and deploy code that can respond to events coming from Google Cloud Services, including, but not limited to, the Firebase family of products. With Cloud Functions, you piece together your application using different products. For instance, a user creates a new Document inside Firestore via the Web app. Consequently, a Cloud Function triggers, and responds to the event of Document Creation. The logic of a Cloud Function depends solely on the business scenario you are implementing. Not only do they let you connect Google Cloud Services together, but they also allow you to create your own set of REST APIs to consume inside your Web or Mobile app. The Cloud Functions project is a wrapper on top of the Google Cloud project. However, it was made easier for developers to configure and use. The two major benefits Cloud Functions offer: Centralize your code in a safe way on Google Cloud Servers. Firebase Cloud Functions run on Google Servers. All of your apps, whether they be Web, Mobile or Desktop, can access and use them. Code security. It is better to save the access codes and keys for Firebase Services on the backend (on the Google Servers) rather than exposing them inside the client-side app code. Cloud Functions are best used to: Trigger code in response to events coming from Firebase products. Perform writes to the Realtime Database and Firestore Upload to your Cloud Storage buckets. Respond to new accounts created in Firebase Authentication. Handle incoming HTTPs Request. Firebase supports two flavors of Cloud Functions: HTTPs triggered Functions Background triggered Functions Unlike Google Cloud Functions, Firebase Cloud Functions support only JavaScript/TypeScript with Node.js. The team is working on including more programming languages. Until then, let’s enjoy JavaScript! HTTPs Triggered Cloud Functions Let’s explore the anatomy of Cloud Functions for HTTPs triggers. Start by ensuring Node.js version >= 8.13.0 is installed on your machine. Next, install the Firebase CLI globally on your computer by running the following command: ` Create a Firebase project by running the commands: ` The next step is to log into Firebase services to connect the new project. Issue this: ` That command opens up a new tab in your default browser to ask for some permissions needed by the Firebase account. Let’s initialize the Firebase project by running the following command: ` This command guides you through a command-line wizard to choose the Firebase features you want to add to the project. For our case, let’s pick the following: Which Firebase CLI features do you want to set up for this folder? *Functions* What language would you like to use to write Cloud Functions? *JavaScript* Do you want to use ESLint to catch probable bugs and enforce style? *Yes* Do you want to install dependencies with npm now? *Yes* That’s all! Let the Firebase CLI do the project scaffolding, and get the project files ready. The command scaffolds a Node.js project, and stores the Cloud Function related code inside the /functions folder. The /functions.package.json lists all the dependencies needed by the Cloud Function. The most important dependencies are: ` Let’s make sure we have the latest bits of these packages by running the following command: ` The /functions/index.js file contains the Cloud Function code. ` The index.js file is a typical Node.js module file that exports a single Cloud Function named helloWorld. You can export more functions as needed. The module starts by requiring the firebase-functions library. This library allows you to create Cloud Functions for HTTPs triggers. It exposes the onRequest() function. This function expects two parameters, the Request and Response objects. The callback function is required to return a Promise by issuing a call for response.send() function. The popular Express.js module for Node.js is behind a Cloud Function for HTTPs trigger. When you deploy a Cloud Function on Firebase, it creates an Express.js app behind the scenes. This app will listen to any HTTPs request for /helloWorld, prepare a Request and Response object, and will call through your Cloud Function, passing it to the two objects. You can include any code inside the onRequest() callback function like you do when writing Express.js apps. > I highly recommend reading this great article on dissecting the Express.js module, and learning how it’s made under the hood. Understanding how Express.js Works Let’s run this Cloud Function locally by issuing the following command: ` The command starts the Firebase Cloud Functions emulator to allow you to run the function locally, without the need to deploy it to Firebase servers. ` Copy & Paste the Function URL into your browser, and you will see a plain text response of Hello from Firebase!. To deploy the Cloud Function to Firebase platform, run the following command: ` > Cloud Functions for HTTPs triggers can only be run under HTTPS and not HTTP. Inside a Cloud Function for HTTPs trigger, you can call any other third party service. You can query the Firestore database, and return data from it, for instance. > You can always refer to the amazing Firebase Cloud Functions documentation to study the full range of capabilities supported by them. Background Triggered Cloud Functions The Background Triggered functions is the other type of functions offered and supported by Firebase. Each and every product in the Firebase family exposes a set of events that are triggered upon a certain action. For example, when a new Document is created inside Firestore, the OnCreate event is triggered. Another example is when a new User is created in the Firebase Authentication module, the onCreate event is triggered. ` The functions object gives access to all supported types of Cloud Functions. This includes both the HTTPs, and Background triggered ones. The example above gives you access to the user that was created. Then, you might decide to send the user an email, or push down a notification to the app. The sky's the limit!! The Firebase Cloud Functions supports all Firebase products, and gives the developer the chance to handle many of the events triggered by them. > For a full list of all the supported background triggered functions, have a look at Trigger background functions The Firebase Cloud Functions documentation is complete, and is extremely helpful to learning all the ins and outs. Therefore, without any further ado, let’s jump into our Notes App Writer, and add a new background triggered Cloud Function. Demo Clone the Notes App Writer at the add-auth branch. This is the branch we worked on in the previous article while authenticating users in the app. Clone the app Run the following command to clone the branch: ` Make sure to install all NPM packages by running this command: ` Add support for Firebase Cloud Functions If you haven’t logged into Firebase before, it’s time to do it by running this command: ` Once you log in, let’s initialize the Firebase services once again to include Functions this time. ` Follow the same steps mentioned in the HTTPs Triggered Cloud Functions section. You will notice a new folder created under the root folder of the project named functions. This folder, as you know by now, holds all the source code for the Cloud Functions in your project. It’s always important, whenever you add support for Cloud Functions in your project, to update the Firebase NPM packages by running the following command: ` Use Environment Variables to store configuration settings Let’s revisit the /firebaseConfig.js file. This file holds the Firebase connection settings as provided by Firebase Console. I will make use of a hidden gem in Vue.js CLI v3, which allows you to use Environment Variables in your application to store such configuration settings. In fact, this is the recommended way of storing configuration settings in a Vue.js app rather than putting them in plain JSON or JavaScript files. The CLI documentation referenced above gives you all the details about the Environment Variable files to use in your app. For now, create a new .env file at the root of the project, and paste the following keys: ` Grab the actual keys from the Firebase Console and place them after they == sign on each and every line. For instance, ` Going back to the firebaseConfig.js file, replace its content with the following: ` Implement the Cloud Function Let’s visit the functions/index.js file, and start implementing our function logic. The purpose of this function is to listen to any new Note Document created inside Firestore, grab its details, and send them in an email. Replace the contents of the index.js file with the following: ` The JavaScript module imports the Firebase Functions Admin SDK libraries. > The Firebase Admin SDK lets you interact with Firebase from privileged environments to perform several actions. The module exposes a single Cloud Function named onNewNoteCreated. This function subscribes to the OnCreate() event handler to run once a new Firestore Document is created. The onCreate() event handler accepts as callback function having two parameters: DocumentSnapshot. EventContext. The former parameter lets you access the content of the Document created, while the latter lets you access the context in which the event has occurred. The next line extracts the body property of the Notes Document. Then, the code extracts the notesId from the EventContext parameter. The variables are then logged to the Cloud Functions Logs database. From my experience, the Cloud Functions Logs is the best tool to debug and test your functions! Finally, the function returns a resolved Promise. I will further discuss the concept of returning Promises from Cloud Functions in the next section of this article. Let’s run the Cloud Function locally first by using the Firebase Functions Shell. Run the following command: `bash onNewNoteCreated({ body: "Hello Firebase Functions!" }, { params: { notesId: "note-#001" }}) `bash 'Successfully invoked function.' firebase > > { eventId: 'c6f8eec2-e7e0-463e-9966-c8c8b0a25505', > timestamp: '2020-02-15T08:12:02.088Z', > eventType: 'google.firestore.document.create', > resource: > { service: 'firestore.googleapis.com', > name: > 'projects/notes-writer-f1s85/databases/(default)/documents/notes/note-#001' }, > params: { notesId: 'note-#001' } } > Hello Firebase Functions! > note-#001 `bash npm install nodemailer `javascript const functions = require('firebase-functions') const admin = require('firebase-admin') const nodemailer = require('nodemailer') admin.initializeApp() var transporter = nodemailer.createTransport({ host: 'smtp.gmail.com', port: 465, secure: true, auth: { user: '', pass: '' } }) exports.onNewNoteCreated = functions.firestore.document('notes/{notesId}').onCreate((snap, context) => { const { body } = snap.data() const { params: { notesId } } = context console.log(body) console.log(notesId) const mailOptions = { from: '', to: '', subject: 'A new note is created', html: ` New Note A new note is created with the following details: Note Id: ${notesId} Note Body: ${body} ` } return transporter.sendMail(mailOptions) .then(() => console.log('Email Sent!')) .catch(error => console.error(error)) }) `bash firebase deploy --only functions `javascript return transporter.sendMail(mailOptions) .then(() => console.log('Email Sent!')) .catch(error => console.error(error)) }) ` The sendMail() function sends an email, and returns a Promise. In our case, we are sending an Email Sent! message to the logs when the Promise is fulfilled. Also, we are logging any errors when the Promise is rejected. At the same time, we are returning the sendMail() Promise to let the Cloud Functions Runner use that Promise to clean up the resources for this function. This only works because JavaScript Promises are chainnable! Conclusion For now, this will be the last episode on Fire the base of Vue.js! series. Firebase is such a big topic, and requires many articles to cover it all. The team at Firebase did a great job at providing decent documentation. Still, I believe, working with the Firebase SDKs will give you experience and knowledge that theory cannot. In the future, I might add episodes to this series. However, in the coming two weeks, I will start a new series on Vue.js development. Stay tuned! Happy Vueing!...

Firebase for user authentication in Vue.js cover image

Firebase for user authentication in Vue.js

And the Firebase goes on! In the first installment of this series, I covered how fast you can kick off your dev life cycle by using the Mirage.js library as a local, and client-side, backend with a REST API in-memory service for your app. In my second, and most recent, [installment] (https://dev.to/thisdotmedia/vue-the-mirage-from-this-angle-352p), I replaced Mirage.js with Cloud Firestore, a serverless database service offered by Firebase. This, of course, makes our app function in a more realistic manner, giving us an overview of it. In this article, I will introduce Firebase User Authentication module to authenticate and authorize users accessing the Notes Writer app. Since my last article, I’ve done a complete face-lift for the Notes Writer app in preparation for user authentication. The app is now more responsive and mobile friendly. Here is a quick preview of the completed app after the addition of the User Authentication Module. The login page, needless to say, is self explanatory. The home page lists the existing notes, allows deleting or editing those notes and the ability to create new ones. This page introduces the Logout button as well. The app is shown on a mobile. You review your existing notes by clicking the burger button located on the left side of the app header bar. The source code of this article can be cloned from this GitHub repo: Notes Writer. Firebase Authentication Firebase Authentication Engine utilizes several methods to authenticate a user on your app via means such as Email with a Password, Phone, Facebook, Twitter, Apple ID, and many other options as shown here. For this article, I will be using the Email/Password provider to authenticate users on the Notes Writer app. > You can always consult with the amazing Firebase Authentication docs here. The Firebase Authentication module is also capable of doing user authorization by allowing administrators to define rules on how users can read, write, delete and edit data stored in the Cloud Firestore. You can read more about securing data in the Cloud Firestore here. Let’s move on, and start coding user authentication in our app! Demo We will be adding the authentication feature on top of the new UI branch of the Notes Writer app. Therefore, start by cloning the Git branch by running this command: git clone --branch new-ui git@github.com:bhaidar/notes-writer.git The command clones the remote new-ui branch by creating a local copy of the branch on your computer. Install Vue Router Start by installing the Vue Router NPM package by running this command: npm install vue-router This command adds the Vue Router library into the app to allow navigation from one route to another. Locate the /src/views folder, and add a new file named Login.vue. Initialize an empty Vue component by pasting the following content into the new file: ` Save the file and switch back to the router/index.js file. Configure Vue Router and routes Now that the Vue Router is installed, and the Login view is created, let’s configure the Vue Router in the app, and define the different routes available for the Notes Writer app. Inside the router/index.js file, start by adding the following imports: ` The firebaseConfig.js file is imported into this file, and is needed later on to check whether the current user is signed-in already. Configure the Vue object to use the Vue Router plugin by adding this line of code: ` This step is required by the Vue engine to install the Vue Router plugin, and make its functionality available to the rest of the app. Next, we need to create a new instance of the VuewRouter object, and define our routes as follows: ` The VueRouter instance defines a catch-all route to redirect users to the Home view. The Home route defines a meta object with a single property of requiresAuth. This boolean value is used later to decide whether the route requires the user to be signed-in before accessing it. Finally, the Login route is defined to load the Login view component. > If you are new to Vue Router plugin I suggest you visit their docs website The Vue Router defines navigation guards and hooks. These guard and hooks are extension points you can implement to change the default behavior of the Vue Router engine when handling a specific route. In our case, we want to implement the beforeEach navigation guard to decide whether the user can access the route he/she intends to visit. The decision is based solely on whether the route at hand requires the user to be authenticated, and that the user is indeed authenticated, and signed-in to the app. ` This hook or navigation guard accepts a single callback function that defines three main input parameters: - to: The route you are navigating to. - from: The route you are coming from. - next: Is a function that is used to move forward to the next hook in the pipeline, to redirect to a new route, to throw an error, and to terminate the current navigation. The callback function above started by checking whether the route the user is navigating to requires authentication. It then uses the Firebase Auth API to get a hand on the currently signed-in user. > You can read more about managing users in Firebase Auth API here. If the route requires authentication, and the user is not signed-in, then redirect the user to the Login view to enter their credentials, and sign-in to the app before visiting the route. If the route doesn’t require authentication, and the user is currently signed-in, then redirect the user to the Home view. If the route doesn’t require authentication, and the user is not signed-in, then let the user continue with the current navigation. For instance, this applies to a user visiting the Login view, or Register view. Finally, if none of the above applies, the user is allowed to route to the desired route. This applies to the Home view. This route requires authentication, and if the user is currently signed-in, then the user is automatically redirected to the Home view. To try this navigation guard, run the app by issuing the following command, and try to navigate to the root page /: ` You are instantly redirected to the login page to sign-in, and access the app. The final step is to tell the Vue about the routes that we defined above. Locate, and open the main.js file, and make sure to pass over the routes object to the root Vue instance as follows: ` Also notice that I’ve moved the initialization of the Vue root app inside the Firebase onAuthStateChanged event handler. This event is usually fired when a change occurs on the currently signed-in user. The user has signed-in, or the user has signed-out. This way, the app won’t initialize before Firebase is fully initialized. Implement Login view Naturally, the next step is to implement the Login view so that users can start accessing the app. Paste the following inside the Login.vue view component: ` The component defines a basic Login form with two fields: Email and Password. Upon clicking the Log In button, the event handler fires: ` The login() function makes use of the Firebase Auth API to sign-in the user using the signInWithEmailAndPassword() function. This function accepts as input both the user’s email and password. If the request is successful, this function returns the currently signed-in user. The code then calls a Vuex Store mutation to store the current signed-in user. In addition, the user is redirected to the home page to start managing the notes. In the case of an error, the code catches it, and informs the user that their sign in attempt failed. The above introduces a new piece of state that we need to manage inside the Vuex Store instance: the currentUser. Let’s build it. Navigate to the store/index.js file, and add the following to the state object: ` Also, add the mutation function as: ` Now the store is ready! Before you can sign-in using the above Login view, we need to set the Firebase sign-in provider on this app. Navigate to the Firebase Console. 1. Click on your app. 2. Click the Authentication menu item. 3. Select the Sign-in method tab. 4. Hover over the first row labeled Email/Password and click the pencil icon to enable this option. Once you enable this provider, make sure to hit the Save button. Next, you need to create a new user on the Firebase Console to test the app with. 1. Select the Users tab. 2. Click the Add user button. Enter a valid email, a strong password and hit the Add user button to save the new user credentials. Now that the backend Firebase is ready, let’s run the app, and test the work that has been done so far! To run the app, issue the following command: ` You enter your newly created user credentials and the app should sign you in to start managing your notes. Add Author ID on Note model Now that you can sign-in to the app, it’s time to introduce the field Author ID onto the Note model object. Every time you create a new Note, the app will grab the ID of the currently signed-in user and attach it on the Note model object to be stored in the Database. Every Note should have an author or owner! This change is minor and affects only the saveNo0te() action inside the Vuex Store instance. Navigate to the /store/index.js file and amend the saveNote() action as follows: ` When creating a new Note record, the code retrieves the currently signed-in User ID and stores this value inside a local variable named authorId. This variable is then passed over to the notesCollection.add() function when creating a new Note record as I’ve just shown in the source code. That’s all! Now every Note created in the system has an owner or author. You will see shortly how we are going to use this feature to query for customized and owned Notes only. Integrate Authentication into the Vuex Store The Vuex Store instance should be updated whenever the status of the currently signed-in user changes. To cater for that, we will refactor the code inside the store object as follows: ` Now the store watches real-time changes on the notesCollection inside the onAuthStatechanged event handler callback. If there is a valid user passed over, the store is updated accordingly. Then the store starts watching any changes on the notesCollection object. Query for User’s own Notes only So far the Vuex Store instance is watching the entire notesCollection object. However, what’s needed is to query only the notes that belong to the currently signed-in user. To achieve this goal, navigate to the store/index.js file, and replace the following line of code: ` With the following line of code: ` The code now fetches Note records that belong to the currently signed-in user! Configure Authorization rules on Firebase Previously in this series, I created the Database and opted for the Start in test mode. This mode allows anyone to read and write to the database for 30 days. Now that we have authentication in place, let’s reassess the Cloud Firestore rules and allow only authenticated users to read, update, create and delete. Follow the steps below to setup authorization on your Cloud Firestore: 1. Visit the Firebase console and login to your account. 2. Locate and click the Database menu item.. 3. Click the Rules tab. Replace the content there with: ` This rule targets any document in the current database and allows any requests that hold an auth object with an uid that’s not null. Only requests sent by an authenticated user, will carry a valid auth object. That’s it! Pretty easy. Now we can be sure that anonymous requests won’t find their way into our database. Add Logout button Finally, let’s add support for a Logout button for the user. Navigate to the components/Navbar.vue component, and insert the following inside the links section: ` Let’s implement the logout() function as follows: ` The code calls the signOut() function on the Firebase Auth API to sign-out the user, and clear any local cookies or data related to the currently signed-in user. In addition, it clears the data stored about the currently signed-in user inside the Vuex Store instance. Finally, it redirects the user to the Login page. Let’s add the clearData() action onto the Vuex Store instance. Navigate to the store/index.js file, and add the following action: ` The action clears out the signed-in user, all loaded Notes records, and the current Note object. Conclusion We’re done! We’ve implemented user authentication in the Notes Writer app using Firebase Authentication API. The Firebase Authentication is rich in features, and offers more functionalities than we could possibly cover in this article. My suggestion: always refer to the Firebase Authentication docs website to learn more about the different options available. In the next installment, we’ll make use of Firebase Cloud Functions to both extend the features of the Notes Writer app, and demonstrate the capabilities of the Cloud Functions. Stay tuned!...

PWA Push Notifications with Firebase (Cloud Messaging)-pt1 cover image

PWA Push Notifications with Firebase (Cloud Messaging)-pt1

Push Notification In Your PWA Have you ever wondered how to add the famous/annoying push notifications to your app? Well, in this tutorial I'm going to show you how to do it using Firebase Cloud Messaging. *Note:* This tutorial requires some basic knowledge on PWAs and Service Workers. You can take a look to my Intro to PWA and Service Workers here and About PWA and notifications here. Before we begin, I need to clarify that the Notification API, and the Push API, are not the same. People get them confused all the time. Push API: The Push API gives web applications the ability to receive messages pushed to them from a server, whether or not the web app is in the foreground, or even currently loaded, on a user agent. This lets developers deliver asynchronous notifications and updates to users that opt in, resulting in better engagement with timely new content. Let's doooo it!! The final code is in the FINAL branch inside of the repo. 1) Clone this repo: https://github.com/devpato/pwa-FCM-notifications-tutorial As you can see, I already have the basic structure of the app created for you, since we are only going to worry about how to send the messages via push notifications using the Firebsae Cloud Messaging service. 2) Navigate to the index.html file. Notice I imported Firebase for you: ` 3) Navigate to Firebase.com, and create an account if you don't have one. 4) Once you are in the Firebase console, navigate to project settings (in case you don't have a project yet - just create it there) 5) Inside of project setting, under the General tab scroll all the way down to find your Firebase SDK snippet (if it's not there yet - this means that you've created a new project, and need to add there an app. Either way, this can be done in the same place where you then will have your SDK snippet - under the General tab). Copy paste it in a safe place. The snippet should look like this: 6) Go to your index.js file, and copy paste the following after the global variables I declared for you. Replace it with your project's customized code - the snippet from step 4. ` 7) Right after - initialize the firebase instance. ` 8) Then, we are going to create a constant called messaging, and will set it to firebase messaging service. ` 9) Time to request permission from firebase cloud messaging. Once we get the thumbs up, they will give us a token as a promise. ` 10) Then, we are going to use the messaging.onMessage() method. This is used for receiving data, and notification payloads, by all users that are currently viewing the page (the page is in the foreground). To do so, we add the following code: ` 11) Notice a firebase-messaging-sw.js file. This file name is going to be searched by the Firebase SDK. The file needs to be in the ROOT of your project. The Firebase SDK will do some magic in the background to register the file as a service worker. 12) Inside of your firebase-messaging-sw.js, initialize the Firebase app by passing in the messagingSenderId. The sender id can be found inside of your project settings as the following image shows. ` 13) Retrieve an instance of Firebase Messaging so that it can handle background messages. ` 14) Background message handler (this one will be invoked when the page is in the backround) ` Test The Notification 15) Run the app using any http server 16) Inside of your Cloud Messaging settings (a tab in the Firebase Console > Project Settings), copy the server key. 17) If you have a Postman http client, do the following: POST URL:* https://fcm.googleapis.com/fcm/send * HEADERS: Content-Type - application/json Authorization - key=server_key BODY: ` Then, click the Send button. At this point, if our app is in the foreground (it is currently opened tab in your browser), then you'll see the message we've sent in the console - handled by messaging.onMessage. But if it is in the background, then it will be handled by messaging.setBackgroundMessageHandler in the service worker, and you'll see something like this: Test your app on a real device by deploying to Firebase or any other hosting provider. If you want to host your app on the Firebase - take a look at my other tutorial. In the next tutorials, I will show you how to successfully subscribe to notifications and push them using the Firebase console....

Storing your notes in the Cloud Firestore with Vue.js cover image

Storing your notes in the Cloud Firestore with Vue.js

In my recent article, we built a Notes Writer Vue.js app that demonstrated how Mirage.js (an in-memory client-side server library) simulates REST API responses for your client-side app. Now, we will take the Notes Writer app to another level by introducing the Cloud Firestore. Firestore is a serverless database service, offered by Google Firebase. We'll use the Cloud Firestore as a backend database for this app to persist and manage the notes. As you go through the article, it will be clear that only the code for the Vuex Store is affected by introducing Cloud Firestore to the app. Some functions become void, and the entire code becomes simpler. This article assumes a basic knowledge of using the Firebase Firestore library API. If you need some additional clarification, I’ve made sure to include some hyperlinks to help you locate what you want, and learn it quickly. The source code of this article can be cloned from this GitHub repo: Notes Writer. Google Firebase The Cloud Firestore is a member of the Google Firebase family. Google Firebase is a Mobile and Web development platform offering cloud-based services to quicken the development process. Some of the products include: Cloud Firestore A serverless real-time NoSQL database engine. Authentication An authentication engine that is capable of authenticating your users via social networks like Google, Twitter, and Facebook, to mention a few. (https://firebase.google.com/docs/auth). Cloud Functions A platform and engine to build, deploy and run Cloud Functions with Google Firebase. Hosting A platform to host your application, whether the app is a static or dynamic app. This platform offers a rich toolbox to test your apps locally before deploying them live. Cloud Storage This service offers developers a bucket to store and serve user-generated content, such as photos, videos, or any other type of files. ML Kit A new member in the Google Firebase family. This service allows developers to introduce Machine Learning services to help solve real-life complex problems. Documentation The Google Firebase team has done a great job offering detailed, and quality documentation, covering all aspects of Firebase. Instead of repeating the same material here, I'll provide the relevant links that will bring you up to speed on Cloud Firestore and Firebase in general. How to add and setup Firebase in your app Cloud Firestore docs Firebase API reference Firebase Libraries Firebase App samples Moving on, we will be using the Cloud Firestore as both a database engine, and a real-time database to listen to new Notes that are being added to the app. Demo Let’s start by creating a new Git branch by running this command: ` The command creates and checks out a new Git branch. Install Firebase There are several approaches to incorporating Firebase in your app. I will install the Firebase NPM package. Let’s go ahead and install this package by running the command: ` This installs all that's required to start developing with Firebase. Create a new Firebase project Before you start using any Firebase service, you must create a new Firebase project. Visit the Firebase Website by pasting the following URL in your browser: Firebase Website. If you are not signed in, you will be redirected to the Sign in/up page. Right after signing in, you are transferred to the Firebase home page. Click the Go to console hyperlink to get started. Click the Add project tile to start creating your first Firebase project. Fill in a name for the new project and accept the Firebase terms and conditions. Once done, click Continue. In the next step, I chose to disable the Google Analytics. You are free to enable it. On the Google Analytics page, locate the Create project button to establish the project. The process usually takes a few seconds to finish setting up everything. A new screen shows up with information about the creation process. Once the new project is ready, click the Continue button to go the project page. Expand the Develop menu. You will be spending most of your time using the features under this menu, and specifically, the Database menu options in this article. Create a new Firebase Web app Now that the Firebase project is created, it’s time to create your first Firebase Web app. A Firebase project consists of multiple apps. For instance, an iOS Mobile backend app, Android Mobile backend app, Web backend app, and other types of apps. For this project, we will be creating a Web backend app. Locate and click the gear icon near the Project Overview menu item. Then, click the Project Setting hyperlink to go to the project settings. On the Project Settings page, you can check the project settings, Web API key, Project ID, and other project-related information. Under the General tab, scroll down to reach the Your apps section. Click the Web App icon as shown below. A new screen pops up to collect some information about your new app before it gets registered under Firebase. Provide a name for the new app. Also, select the option to set up Firebase Hosting for this app. We might be using this option later, but it’s better to select it now. Locate and click the Register app button to get started registering the new app. You may skip the scripts section, and click the Next button right away. You are then asked to install the Firebase CLI that we might use later on to host the Notes Writer app on Firebase. Copy the command and run it locally on your computer to install it globally. Locate the Next button on the screen to move forward. You are given detailed information on how to deploy your app to Firebase. We will skip these steps for now, and come back to it later. Click the Continue to console button to start managing your new app. You are redirected back to the Project Settings page. Scroll down until you find your new Web app section. Locate the section Firebase SDK snippet, and make sure the config option is selected: The firebaseConfig object has all the settings needed to allow your client-side app to connect to Firebase. Copy this object, go back to the code editor, and create a new file named firebaseConfig.js at the root folder of your app. Then, paste this object inside the file. We will revisit this file shortly. Create the database Now that the app is ready, we are free to create an instance of the Cloud Firestore database. Locate and click the Database menu item under the Develop menu. Click the Create database button to create a new database. On the Create database Modal window, make sure you select the Start in test mode option. This removes any restrictions on reading, adding, deleting, and editing data inside the database. Once you are ready for production, you may revisit the database settings, enable the production mode, and define rules for user access permissions. Click the Next button to select a geographical location for this new database. Make sure to select the nearest location to you. Finally, click the Done button. Firebase takes a few seconds to provision the new database. Then, you are redirected to the new Database page to start managing the data. Historically, Firebase supported a realtime database engine. The Cloud Firestore is a successor to that engine, and is the recommended option for almost all scenarios. You can read more about the Firebase Realtime Database. Just as a Relational Database engine structures and defines data in terms of Tables, Rows, and Columns, the Cloud Firestore is a NoSQL database engine structures that defines data in terms of Collections, Documents, and the relationships between Documents and Collections. Let’s create the Notes collection by clicking the Start collection hyperlink. Give your new collection the name of notes. Then click the Next button. Create your first Document by adding the fields that you want to appear on a single Note record. Notice that the Document ID can be auto generated by Firestore, or you can give it a unique value yourself. I choose to keep it managed by Firestore. Starting by adding the body and title fields. Give them both the string data type, and fill in a value. You may add more fields. In this case, I will add the createdOn and updatedOn fields of type timestamp. Once done filling the data, click the Save button. You can now see our new notes collection together with the first document added, and the details of that document. You may add more Notes documents by clicking the Add document hyperlink. You will follow the same process to add new Documents. Now that the database is up and running, let's go back to the Notes Writer app, and start refactoring the code to make use of the Firestore database to load and manage Note in the app. Connect app to Firebase It’s time now to start interacting with the Firebase Firestore from within our Notes Writer app. Revisit the firebaseConfig.js file at the root of the application folder, and paste the following: ` Make sure to copy your own firebaseConfig object from the Firebase app settings. Start by importing the firebase object, and also the firebase/firestore library. Given that you have copied and pasted a valid firebaseConfig object, initialize the communication with Firebase by calling the firebase.initializeApp() function, passing the firebaseConfig object as a parameter. Store an instance of the Firestore client API inside a variable named db. Also, retrieve a reference to the notes collection, and store it inside the variable named notesCollection. Finally, export a few objects to be imported and used in other places in the app. Open the /store/index.js file. Import the firebaseConfig file at the top of the store as follows: ` We are going to use the realtime database feature to get notified when new Notes documents are created so that we load them inside the store. Add the following section outside the store object: ` The key here is to use the onSnapshot() function that is accessible on the notesCollection object. Whenever a new document is added, updated or deleted, the onSnapshot() callback is called with all the information encapsulated inside the querySnapshot variable. The code loops over all the Notes documents returned, populates an array of all notes, and then commits the array to the store by calling the mutation loadNotes. Any time me or someone else creates, updates, or deletes a Note document, the onSnapshot() callback is executed, and therefore, our store is always up to date. The loadNotes mutation is defined as follows: ` I’ve amended the states object to include the following: ` The store now tracks a boolean flag to know whether there is an active request to either delete a Note, add a Note, or update a Note. These flags can be used to show/hide UI in the app, and give a visual feedback to the user of the app. The deleteNote action is defined as follows: ` The action starts by retrieving the note’s details to delete. If there is a valid Note Id, it continues. It starts by setting the setPerformingDelete state flag to true. It issues a call on the Firebase client API to delete a document specifying the Note document ID. It then toggles the value of the setPerformingDelete’ state flag back to false`, signaling the end of deleting a Note document request. Finally, the action resets the current active Note to clear the display. The entire code is wrapped inside atry/catch block. Notice though we are not manually removing the Note document from the Store state. Instead, we just issue a request to delete the Note document. The new list of Notes Documents will be retrieved via the onSnapshot() realtime database feature. Less code for you to write now! Let’s implement the saveNote action: ` The code distinguishes between updating an existing Note document or adding a new one. In both cases, we set the flag to whether the app is updating a record inside Firebase Firestore or adding a new one. In case we are updating an existing Note document, the code calls the update() function on the Note document reference. The updatedOn field is set to a value of fb.firebase.firestore.Timestamp.now(). From the Firebase documentation: > A Timestamp represents a point in time independent of any time zone or calendar, represented as seconds, and fractions of seconds at nanosecond resolution in UTC Epoch time. You can read more information on firebase.firestore.Timestamp In case we are adding a new Note document, the code calls the add() function on the noteColletion object passing as input a Note object including values for createdOn and updatedOn. Finally, the action resets the current active Note to clear the display. You can review the entire store file on Github. One minor change I introduced to the store is removing the getters, and directly accessing state data. If a getter is not doing any logic, there is no need to keep this getter. Simply access the state data directly. Thank you, Simone, for bringing this to my attention! Conclusion This article demonstrates how to integrate Firebase Firestore into your front-end app by giving a step-by-step guide of what's required to create a Firebase app, add a Firestore database, and connect the app to Firebase. Very soon, I will be using the Firebase Authentication to allow users to login to the Notes Writer app, and manage their own set of Notes, independent of other users using the same app. Stay tuned!...

Web App Deployment with Firebase in 2 minutes cover image

Web App Deployment with Firebase in 2 minutes

In this tutorial, I'm going to show you how to deploy your web app to Firebase in 2 minutes! (that's the goal 😏) Setting Up Firebase 1) Go to https://firebase.google.com/, and sign in with your Google account. 2) Go to Console 3) Click on Add project 4) Enter the name of your project 5) Disable Google Analytics 6) Click on Create project 7) Click on Hosting on the left sidebar 8) Now, on the main banner click on Get started 9) Install the Firebase CLI tool in your machine by running: ` Building Your Project 10) Before you can deploy your project, you have to build it. If you are using React or Angular, you can easily do this by running the following command: ` Note: Depending on the tech stack you are using (React, Vue, Angular, etc), a folder will be created after running the build command. This folder will contain your HTML, CSS, JS, etc. Firebase App Setup 11) Inside of your project, open the command line and run: ` 12) Then run: ` 13) Select Hosting 14) Select 'use an exciting project' and select the project you just created in Firebase. 15) When it asks you about the public directory, you select the folder that was created whenever you ran your build command. E.g In React it's build, and in Angular it's dist/Your-project-name 16) When asked to configured as a web app, enter Y 17) When asked about overwriting the index.html type N App Deployment 18) run the following command: ` After a successfull deployment, you should see something like this: Now, clicking on Hosting URL, should open the web app you just deployed. 19) You can also access the hosting url in your Firebase console. You can also setup a custom domain via the console....

Realtime App With Angular and Firestore (AngularFire) cover image

Realtime App With Angular and Firestore (AngularFire)

In this tutorial, I'm going to show you how to use Firestore, which is a realtime database from Firebase with Angular. We are going to make use of the basic CRUD opeartions as well as AGM (Angular Google Maps). Overview This application will help you to have a realtime map with a data table showing your favorite places that you have visted or want to visit, so you can share this info with your friends. Firebase setup 1) Go to Firebase, Sign in with your google account 2) Go to the console 3) Click on Add project 4) Give your project a name 5) Disable Google Analytics for this project 6) Click on Create Project 7) You will see a screen like this. Click on the web icon 8) Register your app 9) Copy the firebaseConfig object, and paste it somewhere secure, we will use it later on 10) Click on Continue to Console 11) Click on the big orange box that says Cloud Firestore 12) Then, on the top, you will see a button that says Create database 13) A modal will show up. Click on radio button Start in test mode 14) Click Next 15) Select your Firestore location 16) Click Done Angular Time to work on our Angular application. 1) Create a new angular app *Note: Make sure to select SCSS as you CSS compiler.* ` 2) Create a component for our form ` 3) Create a component for our list of favorite places ` 4) Create a component for our map with our favorite places ` 5) Create a new service as follow: ` Now, we are going to install all the packages needed, so we don't have to go back to our app.module file and deal with them later. 6) Install firebase ` 7) Install Angular Google Maps (AGM) ` 8) Go to your app.module, and add the following modules as follows ` 9) Generate a Google API Key Also, you'll need to make sure you have Maps JavaScript API service enabled in the Google Service Library 10) Copy the API key, and paste it in the AgmCoreModule inside of the app.module.ts 11) As you can see in the app.module.ts file, we have the following line: ` This line is using the enviroment variable. Go to the enviroment.ts file, and make sure your code looks like the following: ` *Note: Copy/paste the credentials we copied from the firebase console earlier in the tutorial.* 12) Inside of your index.html file, add Semantic UI CDN to give some quick styling to our app ` 13) Add the fontawesome CDN inside the index.html file Get your own CDN link here 14) Create a new model file with the name place.model.ts 15) Copy/paste the following code inside of the place model ` 16) Go to your places-form.components.ts file. We are going to create our form as follows: *Note: I'm also injecting via dependency injection, my places service.* ` 17) Inside of your places-form.component.html, copy/paste the code that contains the form. ` 18) Now, go to your places-form.component.scss file, and add the following styling. ` 19) Time to work with our places-list.component.ts file. Note: In this file, we are going to create an *Input()* that will take the array of places comming from our parent component. Also, notice I'm importing the places service, because we are going to call some actions inside of our service like the delete and edit ` 20) In the places-list.component.html file, you are going create the list that displays your favorite places. The last column will be an actions column. This column will allow you to delete or edit your data. ` 21) Time to style our table :) Lets make it look at least a little decent. Inside of your places-list.component.scss file, add the following code. ` 22) Time to add the favorites places to our map. Open the places-map.component.ts file, and add the following code. Note: As you can see, I'm creating an *Input()* that takes an array of places, which is the data that will populate our markers in the map. ` 23) Let's add the agm map component to our places-map.component.html file. Note: I'm looping throught the array of places to add the markers to our map. ` 24) Don't forget to specify the height of your map, or it won't appear. Specify the height inside of the places-map.component.scss file ` 25) Go to your app.component.ts file. We are going to create a variable that grabs the places stored in our Firestore databse. Note: As you can see, I'm injecting the places services via dependency injection. ` 26) In this step, we are going to add all of our components to app.component.html for them to be displayed in our application. Note: Notices I'm passing the places array to the inputs in the places-list, and places-map components. Also notice I'm using the async pipe to handle the subcription and unsubcription of the observable. ` 27) Let's add the main styling to our app to give it the shell structure. Go your app.component.scss file, and add the following code: ` CRUD with Firestore 28) Go to your places.service.ts, and add the following code: Note: the places$ field is an observable from firestore, and delete, add, update actions are promises. ` Time to run our app! 29) In your command line, run ` Note: You might see an error message telling you that something went wrong with the Google Maps API. In this case, you most probably need to enable billing for this project in your Google Cloud Account. No worries, you won't be charged since there is a free tier available. 30) Create some data, and you should see something like this: 31) Go back to the Firebase console, and see the Firestore console with the new data created. Don't forget to follow me on Twitter @devpato, and let me know what you think about this tutorial!...