<?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: Chioma Halim</title>
    <description>The latest articles on DEV Community by Chioma Halim (@audreyhal).</description>
    <link>https://dev.to/audreyhal</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%2F258359%2F058e10ff-38d0-4e9d-89ca-a2d9113bd973.png</url>
      <title>DEV Community: Chioma Halim</title>
      <link>https://dev.to/audreyhal</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/audreyhal"/>
    <language>en</language>
    <item>
      <title>Why Your Iframe Fails (OAuth, Sandbox &amp; Cross-Origin Security Explained)</title>
      <dc:creator>Chioma Halim</dc:creator>
      <pubDate>Tue, 17 Mar 2026 23:55:52 +0000</pubDate>
      <link>https://dev.to/audreyhal/why-your-iframe-fails-oauth-sandbox-cross-origin-security-explained-3ifj</link>
      <guid>https://dev.to/audreyhal/why-your-iframe-fails-oauth-sandbox-cross-origin-security-explained-3ifj</guid>
      <description>&lt;p&gt;Embedding third-party content with an iframe is straightforward until it suddenly stops working.&lt;/p&gt;

&lt;p&gt;Some pages refuse to render, authentication flows fail, and redirects behave unexpectedly. In most cases, the problem isn’t your code. It’s the browser enforcing security rules around embedded content.&lt;/p&gt;

&lt;p&gt;In this guide, we’ll break down why these restrictions exist and how to work with them. You’ll learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why OAuth does not work inside iframes&lt;/li&gt;
&lt;li&gt;How CSP and &lt;code&gt;X-Frame-Options&lt;/code&gt; control embedding&lt;/li&gt;
&lt;li&gt;How the &lt;code&gt;sandbox&lt;/code&gt; attribute restricts iframe behavior&lt;/li&gt;
&lt;li&gt;How to safely communicate between an iframe and its parent using postMessage.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is an iframe?
&lt;/h2&gt;

&lt;p&gt;An iframe (Inline Frame) is an HTML element that embeds another webpage or external content inside your current page.&lt;/p&gt;

&lt;p&gt;It works like a window that displays content from a different source without redirecting the user.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;iframe&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://example.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;600&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;400&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Example site&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/iframe&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Security Considerations
&lt;/h2&gt;

&lt;p&gt;Some sites intentionally block being loaded inside an iframe. This protects users from clickjacking attacks, where malicious sites visually disguise login forms or sensitive actions. To allow embedding of your site:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set the CSP &lt;code&gt;frame-ancestors&lt;/code&gt; directive with trusted parent domains&lt;/li&gt;
&lt;li&gt;Ensure &lt;code&gt;X-Frame-Options&lt;/code&gt; isn't set to &lt;code&gt;DENY&lt;/code&gt; or &lt;code&gt;SAMEORIGIN&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Best Practice&lt;/strong&gt;: Only allow trusted origins to enable secure iframe embedding.&lt;/p&gt;

&lt;h2&gt;
  
  
  OAuth Restrictions in Iframes
&lt;/h2&gt;

&lt;p&gt;OAuth flows generally do not work inside iframes due to modern browser security controls:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Clickjacking Protection&lt;/strong&gt;&lt;br&gt;
Most providers send headers like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;X-Frame-Options&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Content-Security-Policy&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These block login pages from being embedded, preventing malicious framing attacks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Third-Party Cookie Blocking&lt;/strong&gt;&lt;br&gt;
Browsers restrict cookies in cross-site iframes, which breaks the session handling required for OAuth redirects and state validation. This affects major providers like Google, Facebook, GitHub, etc.&lt;/p&gt;
&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;p&gt;OAuth flows should run in a top-level browsing context, not inside an iframe. e.g&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Redirect OAuth in the Parent Window
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// inside click handler in iframe site&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;top&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;top&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;authUrl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Then allow navigation using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;iframe&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SITE_URL&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;sandbox&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;allow-top-navigation&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/iframe&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Open OAuth in a New Tab:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// iframe site&lt;/span&gt;
&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;authLink&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Allow popups using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;iframe&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SITE_URL&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;sandbox&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;allow-popups&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/iframe&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Iframe &lt;code&gt;sandbox&lt;/code&gt; Attribute
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;sandbox&lt;/code&gt; attribute is a security feature that restricts what embedded content can do. Adding &lt;code&gt;sandbox&lt;/code&gt; with no value applies all restrictions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No scripts&lt;/li&gt;
&lt;li&gt;No form submissions&lt;/li&gt;
&lt;li&gt;Cannot navigate the top-level window&lt;/li&gt;
&lt;li&gt;No popups&lt;/li&gt;
&lt;li&gt;No automatic features (autoplay, pointer lock, etc.).&lt;/li&gt;
&lt;li&gt;By passing a value, you can determine what behaviours you'd like to permit.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Common Sandbox Values for an iframe
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;allow-scripts&lt;/code&gt; — Runs JavaScript inside the iframe&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;allow-forms&lt;/code&gt; — Allows form submissions&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;allow-popups&lt;/code&gt; — Enables opening new windows via window.open()&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;allow-same-origin&lt;/code&gt; — Treats iframe content as same-origin (cookies + DOM access)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;allow-top-navigation&lt;/code&gt; — Lets the iframe redirect the top-level page&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;allow-top-navigation-by-user-activation&lt;/code&gt;— Allows top navigation only after a user click/tap&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;allow-modals&lt;/code&gt; — Enables modal dialogs like alert, confirm, and prompt.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Communication Between an iframe and It's Parent
&lt;/h2&gt;

&lt;p&gt;When embedding an iframe, you may need communication with the parent page. For example, to notify about user actions. Due to the &lt;strong&gt;Same-Origin Policy&lt;/strong&gt;, the parent and iframe cannot directly access each other's DOM or JS if they are on different origins. A standard approach to enabling communication is by using : &lt;code&gt;window.postMessage()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sending a Message (iframe → parent)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;postMessage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;loginSuccess&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://parent-site.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Listening for Messages (parent)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;origin&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://iframe-site.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Always validate &lt;code&gt;event.origin&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Never trust incoming data blindly&lt;/li&gt;
&lt;li&gt;Avoid using &lt;code&gt;"*"&lt;/code&gt; as the target origin unless absolutely necessary&lt;/li&gt;
&lt;li&gt;Ensure the iframe isn't sandboxed without &lt;code&gt;allow-scripts&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>security</category>
    </item>
    <item>
      <title>Push Notifications with Firebase in React.js</title>
      <dc:creator>Chioma Halim</dc:creator>
      <pubDate>Wed, 01 Dec 2021 22:29:32 +0000</pubDate>
      <link>https://dev.to/audreyhal/push-notifications-with-firebase-in-reactjs-1f9i</link>
      <guid>https://dev.to/audreyhal/push-notifications-with-firebase-in-reactjs-1f9i</guid>
      <description>&lt;h3&gt;Introduction&lt;/h3&gt;
&lt;p&gt;Push notifications are &lt;strong&gt;alerts that are "pushed" to a user's device by apps, even when those apps aren't open&lt;/strong&gt;. In the case of web push notifications, the web app receives messages pushed to it from a server at any time. This includes when the application is active or inactive or not open in the browser and when the browser is inactive. Firebase Cloud Messaging is a cross-platform messaging solution that lets you reliably send these messages at no cost.&lt;/p&gt;
&lt;p&gt;In this tutorial, we are going to be walking through how to set up Firebase Cloud Messaging to receive web push notifications in your React.js app.&lt;/p&gt;

&lt;h3&gt;Firebase Setup&lt;/h3&gt;
&lt;p&gt;Create an account at &lt;a href="https://firebase.google.com" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://firebase.google.com" rel="noopener noreferrer"&gt;https://firebase.google.com&lt;/a&gt;, if you don't already have one. Upon successful account creation, you would be navigated to &lt;a href="https://console.firebase.google.com" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://console.firebase.google.com" rel="noopener noreferrer"&gt;https://console.firebase.google.com&lt;/a&gt; afterwards, where you can create a project by clicking on the &lt;strong&gt;Create a project&lt;/strong&gt; button and filling out the necessary fields.&lt;/p&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdkqkweuh7c7xqqno1mgw.png" alt="Firebase Setup Image" width="800" height="390"&gt;

&lt;p&gt;Once project creation is done. Click on the created project and select the platform you want to connect the service to. Since we are working on a web project we can select the &lt;b&gt;web&lt;/b&gt; option by clicking on the (&lt;strong&gt;&amp;gt;&lt;/strong&gt;) icon. This would take us to an interface to &lt;strong&gt;Add Firebase to your web app. &lt;/strong&gt;After filling in the field for &lt;strong&gt;app nickname&lt;/strong&gt; and clicking the&lt;strong&gt; Register app &lt;/strong&gt;button, it should generate a configuration object that we'll need to pass to our React app in later steps.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwff49kjoiawnz7s8k2ac.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwff49kjoiawnz7s8k2ac.png" alt="Firebase Setup Image" width="800" height="390"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvoct5qvoz2zc6p0am9mx.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvoct5qvoz2zc6p0am9mx.gif" alt="Firebase Setup GIF" width="500" height="234"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h3&gt;Connecting Firebase Cloud Messaging to our Application&lt;/h3&gt;
&lt;p&gt;1. Install Firebase in your React project 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;npm install firebase
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;2. Create a new file called &lt;code&gt;firebase.js&lt;/code&gt; and add the following lines of code :&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;initializeApp&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;firebase/app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Replace this firebaseConfig object with the configurations for the project you created on your firebase console. &lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;firebaseConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="c1"&gt;//... &lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nf"&gt;initializeApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;firebaseConfig&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3. Import Firebase's messaging module into the &lt;code&gt;firebase.js&lt;/code&gt; file:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getMessaging&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;firebase/messaging&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;//...&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;messaging&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getMessaging&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4. Create a function called &lt;code&gt;requestForToken&lt;/code&gt; that makes use of Firebase's &lt;a href="https://firebase.google.com/docs/reference/js/messaging_#gettoken" rel="noopener noreferrer"&gt;&lt;code&gt;getToken&lt;/code&gt;&lt;/a&gt; method. This lets you subscribe your app to push notifications. If notification permission has not been granted, this method will ask the user for notification permissions. Otherwise, it returns a token or rejects the promise due to an error.&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//....&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getMessaging&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getToken&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;firebase/messaging&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;//....&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;requestForToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;getToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;messaging&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;vapidKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;REPLACE_WITH_YOUR_VAPID_KEY&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;currentToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;current token for client: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;currentToken&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Perform any other necessary action with the token&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Show permission request UI&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;No registration token available. Request permission to generate one.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;An error occurred while retrieving token. &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: The &lt;code&gt;getToken&lt;/code&gt; method requires you to pass a &lt;em&gt;Voluntary Application Server Identification&lt;/em&gt; or &lt;em&gt;VAPID&lt;/em&gt; key. You can get it by following these steps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Click on &lt;strong&gt;Project Settings&lt;/strong&gt;&lt;em&gt; &lt;/em&gt;for your project from the Firebase console, then navigate to the &lt;strong&gt;Cloud Messaging&lt;/strong&gt; tab and scroll to the &lt;strong&gt;Web configuration&lt;/strong&gt; section. &lt;/li&gt;
&lt;li&gt;Under &lt;strong&gt;Web Push certificates&lt;/strong&gt; tab, click on &lt;strong&gt;Generate key pair&lt;/strong&gt;. &lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;5. Finally, you can link the &lt;code&gt;firebase.js&lt;/code&gt; file to the rest of your project by importing it where it's needed. In this case, we can create a &lt;code&gt;Notification&lt;/code&gt; component:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;requestForToken&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./firebase&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Notification&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nf"&gt;requestForToken&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
 &lt;span class="c1"&gt;//....&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;h4&gt;Additional Step: &lt;/h4&gt;
&lt;p&gt;The messaging service requires a &lt;code&gt;firebase-messaging-sw.js&lt;/code&gt; file to work fine. I'll explain more about this file in the &lt;strong&gt;Background Listener Setup &lt;/strong&gt;section of this guide. For now, create an empty file named &lt;code&gt;firebase-messaging-sw.js&lt;/code&gt; in the public folder of your project.&lt;/p&gt;
&lt;p&gt;Navigate to the browser console of your app to test if our app can connect to Firebase Cloud Messaging service. You should see the token that was received, if successful.&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9f098j2aceg3n9yffahi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9f098j2aceg3n9yffahi.png" alt="firebase-push-notification-image" width="800" height="371"&gt;&lt;/a&gt; &lt;/p&gt;


&lt;h4&gt;Something went wrong?&lt;/h4&gt;
&lt;p&gt;1.) If you got an error concerning &lt;em&gt;&lt;strong&gt;permissions not being granted but blocked instead&lt;/strong&gt;&lt;/em&gt;, you should make sure you set notifications permissions to &lt;em&gt;&lt;strong&gt;Allow&lt;/strong&gt;&lt;/em&gt; in your browser.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkr5b905l5ddbuovlojua.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkr5b905l5ddbuovlojua.png" alt="firebase-push-notification-image" width="800" height="414"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2.) If you got an error concerning a &lt;em&gt;&lt;strong&gt;missing required authentication credential&lt;/strong&gt;, &lt;/em&gt;then you probably passed the wrong &lt;strong&gt;VAPID_KEY&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdv6f6fao1kjqcj401crn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdv6f6fao1kjqcj401crn.png" alt="firebase-push-notification-image&amp;lt;br&amp;gt;
![firebase-push-notification-image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wd52pv94dphzsm2lwrxc.png)" width="800" height="374"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;Receiving Messages&lt;/h3&gt;
&lt;p&gt;Now that the initial setup is done, you'll need to configure message listeners. Foreground message listeners are called when the page has focus(i.e. when the user is on the browser tab containing our web app), while background message listeners are called when the user is on a different tab or even when the tab containing our app is closed.&lt;/p&gt;
&lt;h4&gt;Foreground Listener Setup&lt;/h4&gt;
&lt;p&gt;To handle messages when the app is in the foreground, you can make use of Firebase's &lt;code&gt;&lt;a href="https://firebase.google.com/docs/reference/js/messaging_#onmessage" rel="noopener noreferrer"&gt;onMessage&lt;/a&gt;&lt;/code&gt; method in your &lt;code&gt;firebase.js&lt;/code&gt; file:&lt;/p&gt;
&lt;br&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getMessaging&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onMessage&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;firebase/messaging&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;//......&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;messaging&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getMessaging&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;//......&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;onMessageListener&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;onMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;messaging&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;payload&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You can then call the method in the &lt;code&gt;Notification&lt;/code&gt; component. For this tutorial, I'm making use of &lt;a href="https://react-hot-toast.com/" rel="noopener noreferrer"&gt;&lt;em&gt;react-hot-toast&lt;/em&gt;&lt;/a&gt; library to create a toast UI for displaying the notification details received from the message listener.&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;toast&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Toaster&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-hot-toast&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;requestForToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onMessageListener&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./firebase&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Notification&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;notification&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setNotification&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;notify&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;toast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ToastDisplay&lt;/span&gt;&lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ToastDisplay&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;notification&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/b&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;notification&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;notification&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="p"&gt;){&lt;/span&gt;
     &lt;span class="nf"&gt;notify&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;notification&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

  &lt;span class="nf"&gt;requestForToken&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="nf"&gt;onMessageListener&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;setNotification&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;notification&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;notification&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;     
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;failed: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
     &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Toaster&lt;/span&gt;&lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Notification&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;h4&gt;Background Listener Setup&lt;/h4&gt;
&lt;p&gt;To handle background messages, you'd need to make use of a &lt;strong&gt;service worker&lt;/strong&gt;. A service worker is a script that your browser runs in the background, separate from the web page, enabling features that do not require a web page or user interaction.&lt;/p&gt;
&lt;p&gt;You can go ahead to add the following lines of code to your &lt;code&gt;firebase-messaging-sw.js&lt;/code&gt; file :&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Scripts for firebase and firebase messaging&lt;/span&gt;
&lt;span class="nf"&gt;importScripts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://www.gstatic.com/firebasejs/8.2.0/firebase-app.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;importScripts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://www.gstatic.com/firebasejs/8.2.0/firebase-messaging.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Initialize the Firebase app in the service worker by passing the generated config&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;firebaseConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`REPLACE_WITH_YOUR_FIREBASE_MESSAGING_API_KEY`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;authDomain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`REPLACE_WITH_YOUR_FIREBASE_MESSAGING_AUTH_DOMAIN`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;projectId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`REPLACE_WITH_YOUR_FIREBASE_MESSAGING_PROJECT_ID`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;storageBucket&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`REPLACE_WITH_YOUR_FIREBASE_MESSAGING_STORAGE_BUCKET`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;messagingSenderId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`REPLACE_WITH_YOUR_FIREBASE_MESSAGING_SENDER_ID`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;appId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`REPLACE_WITH_YOUR_FIREBASE_MESSAGING_APP_ID`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;measurementId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`REPLACE_WITH_YOUR_FIREBASE_MESSAGING_MEASUREMENT_ID`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;firebase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;initializeApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;firebaseConfig&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Retrieve firebase messaging&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;messaging&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;firebase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;messaging&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;messaging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onBackgroundMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Received background message &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
 &lt;span class="c1"&gt;// Customize notification here&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;notificationTitle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;notification&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;notificationOptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;notification&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;registration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;showNotification&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;notificationTitle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;notificationOptions&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;h3&gt;Testing Notifications&lt;/h3&gt;
&lt;p&gt;To test whether the notifications are functional, you can trigger a test notification from the firebase console with the following steps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;On your project dashboard, scroll to the &lt;strong&gt;Cloud Messaging &lt;/strong&gt;section.&lt;/li&gt;
&lt;li&gt;Under the &lt;strong&gt;Notifications&lt;/strong&gt; tab, click on the &lt;strong&gt;New notification &lt;/strong&gt;button&lt;/li&gt;
&lt;li&gt;Fill in the information for &lt;strong&gt;Notification title&lt;/strong&gt; and &lt;strong&gt;Notification text&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Under the &lt;strong&gt;Device preview&lt;/strong&gt; section, click on &lt;strong&gt;Send test message&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;In the popup that opens, enter the &lt;strong&gt;client token&lt;/strong&gt; that is logged in the console as the FCM registration token and press the &lt;strong&gt;+&lt;/strong&gt; button&lt;/li&gt;
&lt;li&gt;Make sure that the FCM token is checked and click on &lt;strong&gt;Test&lt;/strong&gt;. You could also decide to fill in the entire&lt;strong&gt; Compose notification&lt;/strong&gt; section and press the &lt;strong&gt;Review&lt;/strong&gt; button at the bottom of the page to have it sent to multiple target apps.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you're on the browser tab with the app opened, you should see a notification pop up. &lt;/p&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F86k1tryby1shaq5i5g78.png" alt="firebase-push-notification-image" width="800" height="551"&gt;&lt;br&gt;&lt;p&gt;While if the browser tab with the application isn't in focus, you should see a default system notification pop-up.&lt;/p&gt;
&lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhvusgoz1bmrto727fm9t.png" alt="firebase-push-notification-image" width="800" height="369"&gt;&lt;br&gt;&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; To see a notification banner when notifications are received in the background, make sure to turn on the feature for your browser under your system's notification settings.&lt;/p&gt;
&lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F67vd8osmwt7lire8rv4u.png" alt="firebase-push-notification-image" width="800" height="430"&gt;&lt;br&gt;&lt;h3&gt;&lt;/h3&gt;
&lt;h4&gt;Something went wrong ?&lt;/h4&gt;
&lt;p&gt;There may be cases where a user doesn't get notifications immediately or at all. This can be due to a variety of reasons, some of which are covered &lt;a href="https://www.pushengage.com/why-your-web-push-notification-lower-reach-than-expected/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;Repository Code&lt;/h4&gt;
&lt;p&gt; You can find the GitHub repo for this tutorial at &lt;a href="https://github.com/AudreyHal/React-Firebase-Cloud-Messaging-Demo" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://github.com/AudreyHal/React-Firebase-Cloud-Messaging-Demo" rel="noopener noreferrer"&gt;https://github.com/AudreyHal/React-Firebase-Cloud-Messaging-Demo&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>firebase</category>
    </item>
    <item>
      <title>Persisting Files in Javascript (React) Applications</title>
      <dc:creator>Chioma Halim</dc:creator>
      <pubDate>Wed, 24 Mar 2021 18:56:48 +0000</pubDate>
      <link>https://dev.to/audreyhal/persisting-files-in-javascript-react-applications-3fah</link>
      <guid>https://dev.to/audreyhal/persisting-files-in-javascript-react-applications-3fah</guid>
      <description>&lt;p&gt;While working on a React application, you might come across scenarios where you need to store some files on the client-side to be used across different views before sending them to the server or you may want to be able to store large amounts of data on the client-side for offline access. For any of these scenarios, we would need a mechanism to be able to persist these files appropriately in our browser. In this post, I'll be covering how that can be achieved.&lt;/p&gt;

&lt;h1&gt;
  
  
  What not to do
&lt;/h1&gt;

&lt;p&gt;Before we get into how to properly persist our files, we are going to be looking at the limitations of other methods that one might consider.&lt;/p&gt;

&lt;p&gt;This involves assigning values to variables that make up parts of the browser URL.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://example.com/cakes?flavour=chocolate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For React applications with routing set up, it's fairly common to see some information being passed across components pointing to different routes. This information can be easily retrieved when after a page refresh as long as the route information remains unchanged.&lt;/p&gt;

&lt;p&gt;In the case of transmitting files, this won't work because URL params are in string formats and file objects aren't &lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/Serialization" rel="noopener noreferrer"&gt;serializable&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Attempting to serialize the file in the first component and retrieving the parsed file object in the second component via URL params would return an object with missing file information.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using Local Storage
&lt;/h3&gt;

&lt;p&gt;LocalStorage is a property that allows web applications to store data locally within the user's browser as key/value pairs  with no expiration date.&lt;/p&gt;

&lt;p&gt;It stores up to 5-10MB of data (depending on the browser) and making use of it is as easy as shown below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Jason&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// Saves data to localStorage object&lt;/span&gt;

&lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Retrieves data using key&lt;/span&gt;

&lt;span class="c1"&gt;//=&amp;gt;  'Jason'&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;LocalStorage can also only store data in string format. This presents a problem for storing files since files aren't serializable data types.&lt;/p&gt;

&lt;p&gt;It is possible to &lt;a href="https://www.tutorialspoint.com/convert-image-to-data-uri-with-javascript" rel="noopener noreferrer"&gt;convert image files into a base64 encoded data URI&lt;/a&gt;, which is a serialized format, and then proceed to save it in local storage. But this is not optimal because both data URI's and local storage have size limits across different browsers.&lt;/p&gt;

&lt;p&gt;Note: The same set of limitations apply for applications using a tool like Redux Persist, which is a library allowing developers to save the redux store in the localStorage of the browser. Both localStorage and &lt;a href="https://redux.js.org/style-guide/style-guide#do-not-put-non-serializable-values-in-state-or-actions" rel="noopener noreferrer"&gt;Redux&lt;/a&gt; don't store non-serializable data types, like files.&lt;/p&gt;

&lt;h1&gt;
  
  
  What you can do
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Using IndexedDB
&lt;/h3&gt;

&lt;p&gt;IndexedDB is a local database provided by the browser. It is more powerful than local storage and lets you store large amounts of data. Unlike local storage, in which you can only store strings, it lets you store all data types, including objects.&lt;/p&gt;

&lt;h4&gt;
  
  
  Features
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Stores key-pair values:&lt;/strong&gt; It uses an object store to hold data. In the object store, the data is stored in the form of "key-value pairs". Each data record has its own corresponding primary key, which is unique and can't be repeated. Duplication of a primary key would result in an error being thrown.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Asynchronous:&lt;/strong&gt; Operations with IndexedDB can be performed side by side with other user operations because it doesn't block the main browser thread, unlike localStorage, which is synchronous. This prevents reading and writing of large amounts of data from slowing down the performance of the web page.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Limits data access to the same domain:&lt;/strong&gt; Each database corresponds to the domain name that created it. The web page can only access the database which is under its own domain name, but not a cross-domain database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Support transactions:&lt;/strong&gt; This means that as long as one of a series of the steps fails, the entire transaction will be canceled, and the database is rolled back to the state before the transaction occurred. So there is no case where only a part of the data is rewritten.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Supports all data types:&lt;/strong&gt; IndexedDB isn't limited to storing just strings, but can also store anything that can be expressed in JavaScript, including &lt;a href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Boolean" rel="noopener noreferrer"&gt;boolean&lt;/a&gt;, &lt;a href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Number" rel="noopener noreferrer"&gt;number&lt;/a&gt;, &lt;a href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String" rel="noopener noreferrer"&gt;string&lt;/a&gt;, &lt;a href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date" rel="noopener noreferrer"&gt;date&lt;/a&gt;, &lt;a href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object" rel="noopener noreferrer"&gt;object&lt;/a&gt;, &lt;a href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array" rel="noopener noreferrer"&gt;array&lt;/a&gt;, &lt;a href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp" rel="noopener noreferrer"&gt;regexp&lt;/a&gt;, &lt;a href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/undefined" rel="noopener noreferrer"&gt;undefined&lt;/a&gt;, and null. It also allows storing blobs and files, which applies to our use case in this tutorial.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;IndexedDB API is low-level and may seem a bit daunting to use to some. For this reason, libraries such as &lt;a href="https://localforage.github.io/localForage/" rel="noopener noreferrer"&gt;localForage&lt;/a&gt;, &lt;a href="https://dexie.org/" rel="noopener noreferrer"&gt;dexie.js&lt;/a&gt;, &lt;a href="https://github.com/erikolson186/zangodb" rel="noopener noreferrer"&gt;ZangoDB&lt;/a&gt;, &lt;a href="https://pouchdb.com/" rel="noopener noreferrer"&gt;PouchDB&lt;/a&gt;, &lt;a href="https://www.npmjs.com/package/idb" rel="noopener noreferrer"&gt;idb&lt;/a&gt;, &lt;a href="https://www.npmjs.com/package/idb-keyval" rel="noopener noreferrer"&gt;idb-keyval&lt;/a&gt;, &lt;a href="https://jsstore.net/" rel="noopener noreferrer"&gt;JsStore&lt;/a&gt; and &lt;a href="https://github.com/google/lovefield" rel="noopener noreferrer"&gt;lovefield&lt;/a&gt; provide a simpler API that makes IndexedDB more programmer-friendly.&lt;/p&gt;

&lt;p&gt;I'm going to be demonstrating how to store an object using the LocalForage JavaScript library. This is a wrapper that provides a simple &lt;code&gt;name: value&lt;/code&gt; syntax for client-side data storage, which uses IndexedDB in the background but falls back to WebSQL and then localStorage in browsers that don't support IndexedDB.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example
&lt;/h4&gt;

&lt;p&gt;To install this, simply run&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 localforage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;LocalForage syntax imitates that of localStorage but with the &lt;a href="https://localforage.github.io/localForage/#data-api-setitem" rel="noopener noreferrer"&gt;ability to store many types of data&lt;/a&gt; instead of just strings. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="na"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Doe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;localForage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;person&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Saves data to an offline store&lt;/span&gt;

&lt;span class="nx"&gt;localForage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;person&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Retrieves item from the store&lt;/span&gt;

&lt;span class="c1"&gt;//=&amp;gt;  {&lt;/span&gt;
&lt;span class="c1"&gt;//     firstName:"John", &lt;/span&gt;
&lt;span class="c1"&gt;//     lastName:"Doe",&lt;/span&gt;
&lt;span class="c1"&gt;//   };&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Using a Class Module Instance
&lt;/h3&gt;

&lt;p&gt;IndexedDB is great for offline storage and comes with a lot of capabilities but may seem like an overkill for simple instances where you simply want to persist some files into memory and access them temporarily.&lt;/p&gt;

&lt;p&gt;We can achieve this by creating a simple class module as a form of abstraction, then exposing its instance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StoredFiles&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;saveFiles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;getFiles&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;resetValues&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;uploads&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;StoredFiles&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Creates an instance of StoredFiles class&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;uploads&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can easily import the uploads in any file we need and access the methods of StoredFiles. For saving the files in memory, we can run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;uploads&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;saveFiles&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;file1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;file2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Afterwards, we can retrieve the files in any other component by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;uploads&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getfiles&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;  

&lt;span class="c1"&gt;//=&amp;gt; ["file1", "file2"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can clear the values when we are done by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;uploads&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resetValues&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>react</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
