<?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: Samir Tiwari</title>
    <description>The latest articles on DEV Community by Samir Tiwari (@samirtiwari).</description>
    <link>https://dev.to/samirtiwari</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%2F2259555%2F517e65c9-f529-4e72-a103-d9ad32282d79.png</url>
      <title>DEV Community: Samir Tiwari</title>
      <link>https://dev.to/samirtiwari</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/samirtiwari"/>
    <language>en</language>
    <item>
      <title>Create an AI Chatbot for Your Website: A Step-by-Step Guide to RAG Implementation</title>
      <dc:creator>Samir Tiwari</dc:creator>
      <pubDate>Wed, 23 Apr 2025 15:15:09 +0000</pubDate>
      <link>https://dev.to/samirtiwari/create-an-ai-chatbot-for-your-website-a-step-by-step-guide-to-rag-implementation-54i3</link>
      <guid>https://dev.to/samirtiwari/create-an-ai-chatbot-for-your-website-a-step-by-step-guide-to-rag-implementation-54i3</guid>
      <description>&lt;p&gt;In today's digital landscape, there's a lot of excitement surrounding AI, AI agents, and AI chatbots. In this blog, we'll explore how to create your own AI chatbot for your website. We'll also delve into the fundamentals of RAG (Retrieval-Augmented Generation), showing you how to gather information from your site and leverage AI to build a chatbot that truly understands your content.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Understanding the Flow: How RAG Works&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Before jumping into code, let's understand what we're going to do and what tools we'll need. We'll use Node.js, Express.js, and TypeScript for our backend, Qdrant as our vector database, and Gemini from Google for our AI (why Gemini? Because it has a super generous free plan!)&lt;/p&gt;

&lt;p&gt;But hey, don't worry too much about the specific technologies, there are plenty of options out there. What's most important is understanding how the system works, since this forms the foundation for all RAG applications. This knowledge will be super helpful for building AI agents or chat bots in the future, so don't skip this part!&lt;/p&gt;

&lt;p&gt;The flow is actually pretty simple:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;First, we scrape our website to gather context about it for our AI. You could also use other formats like PDFs to provide context.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We need a pool of information from which we can search for content related to what users ask our chatbot.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;But how do we retrieve only the relevant information? That's where our hero Qdrant comes in! Qdrant is an open-source vector database and similarity search engine designed to handle high-dimensional vectors. There are other vector databases available too, so feel free to use whatever works for you.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once we have both the user's question and the related information, we can use AI to create a good response using the information from our vector database and send it back to the user.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's summarize the flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Retrieve information from our website&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Save that information in our vector database&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;User asks a question to our AI chat bot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Based on the question, retrieve relevant information from our vector database&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use AI (Gemini AI) to create a great response using the retrieved information&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You might wonder, how does the vector database fetch information based on the user's question? This is where vector embeddings come in. In simple terms, vector embeddings are just bunches of floating-point numbers that represent text in a way AI can understand and compare.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Let's Start Coding!&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Now that you understand the theory, let's dive into the code.&lt;/p&gt;

&lt;p&gt;First, let's set up our backend. Feeling bored about setting up a basic backend? No worries! You can directly run this command in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm create basic-express-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is my own npm package 😎 that sets up a basic Express server in JavaScript or TypeScript.&lt;/p&gt;

&lt;p&gt;Next, let's install all our dependencies. Run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i @google/genai @qdrant/js-client-rest axios uuid
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Setting Up Our Vector Database&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;As outlined in our flow, we first need to collect information from our website. But before that, let's create two functions: one to create vector embeddings from text, and another to save these to our vector database.&lt;/p&gt;

&lt;p&gt;Let's start with the vector database. You can use Docker or create a cluster in the cloud. I'm using a cluster that I created in Qdrant cloud. Make sure you have Qdrant's URL and key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { QDRANT_KEY, QDRANT_URL } from "./config.js";const qdrantClient = new QdrantClient({ url: QDRANT_URL, apiKey: QDRANT_KEY, checkCompatibility: false,});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can use this function to insert information into the database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const WEB_COLLECTION_NAME = "my_portfolio_web";const VECTOR_SIZE = 3072;export const insertInDB = async ( embedding: number[], url: string, body: string = "", head: string = ""): Promise&amp;lt;void&amp;gt; =&amp;gt; { try { const { exists } = await qdrantClient.collectionExists(WEB_COLLECTION_NAME); if (!exists) { await qdrantClient.createCollection(WEB_COLLECTION_NAME, { vectors: { size: VECTOR_SIZE, distance: "Cosine", }, }); } await qdrantClient.upsert(WEB_COLLECTION_NAME, { wait: true, points: [{ id: uuidv4(), vector: embedding, payload: { url, head, body }, },], }); } catch (error) { throw new ErrorHandler("Failed to insert data into database", 500); }};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: I'm using a custom error handler here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;throw new ErrorHandler("Failed to insert data into database", 500);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;size&lt;/code&gt; parameter represents the dimensions of the vector embedding. Gemini's &lt;code&gt;gemini-embedding-exp-03-07&lt;/code&gt; model has 3072 dimensions. This might differ for different models.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Creating Vector Embeddings&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Now that we have a function to insert information into our database, let's create a function that generates vector embeddings. For this, we need the API key for our AI to use the embedding model. Make sure you have your API key ready.&lt;/p&gt;

&lt;p&gt;To create embeddings using Gemini's &lt;code&gt;gemini-embedding-exp-03-07&lt;/code&gt; model, first initialize Gemini like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { GoogleGenAI} from "@google/genai";export const ai = new GoogleGenAI({ apiKey: AI_API_KEY!,});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And now let's create a function that generates vector embeddings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { GenerateContentResponse } from "@google/genai";export const generateVectorEmbedding = async ( text: string): Promise&amp;lt;number[]&amp;gt; =&amp;gt; { try { const response = await ai.models.embedContent({ model: "gemini-embedding-exp-03-07", contents: text, }); const embeddings = response.embeddings ?? []; if (!embeddings || embeddings.length === 0 || !embeddings[0]?.values) { throw new ErrorHandler("Failed to generate embedding", 500); } const res = embeddings ? embeddings[0]?.values : []; return res; } catch (error) { throw new ErrorHandler("Failed to generate vector embedding", 500); }};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Collecting Website Information&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Now let's get the information we'll save in our vector database. I'm scraping my portfolio website to get this information, you can scrape your own website. Here's a function to scrape a website:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export async function scrape(url: string): Promise&amp;lt;ScrapeResult&amp;gt; { try { const response: AxiosResponse&amp;lt;string&amp;gt; = await axios.get&amp;lt;string&amp;gt;(url); const $ = cheerio.load(response.data); const head = $("head").html() ?? ""; const sections: string[] = []; $("section").each((_, el) =&amp;gt; { const html = $(el).html(); if (html) sections.push(html); }); return { head, sections }; } catch (error) { throw new ErrorHandler("Failed to scrape the URL", 500); }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we're using axios to get the website content and cheerio to help us extract specific tags.&lt;/p&gt;

&lt;p&gt;Note: You'll need to adapt two things according to your needs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;I'm specifically targeting &lt;code&gt;section&lt;/code&gt; tags because that's how my website is structured. I'm getting an array of sections as a way to chunk the information. You'll need to find your own way to chunk information that works for your site.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You could write this as a recursive function to extract all &lt;code&gt;a&lt;/code&gt; tags and get information from those URLs recursively. Just make sure there's a stopping condition so it doesn't run infinitely!&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Ingesting Information to the Database&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Now that we have the information, let's create a function that ingests it into the database using the three functions we've created:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const ingest = async (url: string): Promise&amp;lt;void&amp;gt; =&amp;gt; { try { const { head, sections } = await scrape(url); if (!sections || !head) { throw new ErrorHandler("Failed to ingest the url", 400); } for (const section of sections) { const embedding = await generateVectorEmbedding(section); await insertInDB(embedding, url, section, head); } } catch (error) { throw new ErrorHandler("Failed to ingest URL", 500); }};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to save information from PDFs instead, you can use this function. Just make sure you install &lt;code&gt;unpdf&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { extractText, getDocumentProxy } from "unpdf";export const pdfToPageChunks = async (pdfBuffer: Buffer): Promise&amp;lt;string[]&amp;gt; =&amp;gt; { try { const pdf = await getDocumentProxy(new Uint8Array(pdfBuffer)); const { text } = await extractText(pdf, { mergePages: false }); // using mergePages:false won't merge the pages so that we get text as array if (Array.isArray(text)) { return text; } else { return [text]; } } catch (error) { throw new ErrorHandler("Failed to parse PDF", 500); }};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Retrieving Relevant Information&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Now that we've saved the information, we can retrieve it based on user questions. Let's create a function that searches the database based on embeddings of users' questions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const retrieveByEmbedding = async ( queryEmbedding: number[], k: number = 3): Promise&amp;lt;string[]&amp;gt; =&amp;gt; { try { const searchResult = await qdrantClient.search(WEB_COLLECTION_NAME, { vector: queryEmbedding, limit: k, }); return searchResult.map((hit) =&amp;gt; (hit.payload?.body as string) ?? ""); } catch (error) { throw new ErrorHandler("Failed to retrieve data from database", 500); }};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can generate embeddings for the user's question using the function we created earlier.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Creating the Chat Function&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Now that we have everything set up, let's create a function that returns a good response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const chat = async (question: string = ""): Promise&amp;lt;string&amp;gt; =&amp;gt; { try { const questionEmbedding = await generateVectorEmbedding(question); const contextBodies: string[] = await retrieveByEmbedding( questionEmbedding ); const prompt = ` Context: ${contextBodies.join("\n\n")} User Question: ${question} Answer: `;const response: GenerateContentResponse = await ai.models.generateContent({ model: "gemini-2.0-flash", contents: prompt, config: { systemInstruction: ` You are a helpful assistant for a website that answers user questions based on provided context. `, }, }); return response.text ?? ""; } catch (error) { throw new ErrorHandler("Failed to generate response", 500); }};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: Make sure to provide more detailed system instructions for better results!&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Handling Conversation History&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;If you want the AI to remember previous conversations, you can use Gemini's multi-turn conversation feature like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const chat = ai.chats.create({ model: "gemini-2.0-flash", history: history: [{ role: "user", parts: [{ text: "Hello" }], }, { role: "model", parts: [{ text: "Great to meet you. What would you like to know?" }], }, ],});const response1 = await chat.sendMessage({ message: "Can you telle me about new features?.", });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Hooray! You now have a chat bot that can answer questions about your business or website. The bot uses information directly from your site to provide relevant, accurate responses to users.&lt;/p&gt;

&lt;p&gt;If you want to see the complete code, you can check out my &lt;a href="https://github.com/tiwarisamir/blog-ai-chatbot" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While you could use frameworks like Langchain if you prefer, the basic flow of RAG applications will be very similar to what we've covered here. Understanding these fundamentals will help you build more sophisticated AI solutions in the future!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>rag</category>
      <category>chatbot</category>
      <category>qdrant</category>
    </item>
    <item>
      <title>Enhance Your React App with Firebase Push Notifications in TypeScript</title>
      <dc:creator>Samir Tiwari</dc:creator>
      <pubDate>Wed, 07 Aug 2024 18:41:22 +0000</pubDate>
      <link>https://dev.to/samirtiwari/enhance-your-react-app-with-firebase-push-notifications-in-typescript-bmn</link>
      <guid>https://dev.to/samirtiwari/enhance-your-react-app-with-firebase-push-notifications-in-typescript-bmn</guid>
      <description>&lt;p&gt;Push notifications are a must-have feature for your website when you want to keep users in the loop about important events. You can show these notifications either when your website is open (foreground) or even when it's not the active tab in your browser (background). Firebase provides an awesome tool called Cloud Messaging to make this happen. In this blog, well walk through how to add push notifications to a React app.&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting Started
&lt;/h3&gt;

&lt;p&gt;First, head over to the Firebase Console and create a new project. Once that's done, add a new app to your project by selecting the web option since well be adding notifications to a website. After registering your app, you'll see some code under "Add Firebase SDK" go ahead and copy all that.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting Up Firebase in Your React App
&lt;/h3&gt;

&lt;p&gt;Assuming you already have a React app set up, install the Firebase package with:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Now, create a file called &lt;code&gt;firebase.ts&lt;/code&gt; and paste the code you copied from Firebase. You'll also need to import &lt;code&gt;getMessaging&lt;/code&gt; from &lt;code&gt;firebase/messaging&lt;/code&gt; and pass &lt;code&gt;app&lt;/code&gt; to &lt;code&gt;getMessaging&lt;/code&gt;. Here's how your &lt;code&gt;firebase.ts&lt;/code&gt; file should look:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// firebase.ts&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;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="s2"&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="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="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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;YOUR_VITE_FIREBASE_API_KEY&lt;/span&gt;&lt;span class="dl"&gt;"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;YOUR_VITE_FIREBASE_AUTH_DOMAIN&lt;/span&gt;&lt;span class="dl"&gt;"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;YOUR_VITE_FIREBASE_PROJECT_ID&lt;/span&gt;&lt;span class="dl"&gt;"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;YOUR_VITE_FIREBASE_STORAGE_BUCKET&lt;/span&gt;&lt;span class="dl"&gt;"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;YOUR_VITE_FIREBASE_MESSAGING_SENDER_ID&lt;/span&gt;&lt;span class="dl"&gt;"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;YOUR_VITE_FIREBASE_APP_ID&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&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="k"&gt;export&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="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Generating a FCM Token
&lt;/h3&gt;

&lt;p&gt;To send notifications, you need a fcm token. Import &lt;code&gt;getToken&lt;/code&gt; from &lt;code&gt;firebase/messaging&lt;/code&gt; and create a function, say &lt;code&gt;GenerateToken&lt;/code&gt;, in your &lt;code&gt;firebase.ts&lt;/code&gt; file. Alternatively, you could make it in a separate file, just remember to export it. You can call this function in &lt;code&gt;App.tsx&lt;/code&gt; so the token is generated when the website loads. Inside this function, request notification permission from the browser. If granted, call &lt;code&gt;getToken&lt;/code&gt;, which takes &lt;code&gt;messaging&lt;/code&gt; and &lt;code&gt;vapidKey&lt;/code&gt; as arguments.&lt;/p&gt;

&lt;p&gt;To get the &lt;code&gt;vapidKey&lt;/code&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Go to your project in Firebase Console.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click the settings gear next to "Project Overview" and choose "Project Settings."&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click on "Cloud Messaging."&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Under "Web configuration," click "Generate key pair" to get your &lt;code&gt;vapidKey&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now use that key in &lt;code&gt;getToken&lt;/code&gt; inside &lt;code&gt;GenerateToken&lt;/code&gt;. Here's how it should look:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// firebase.ts&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;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="s2"&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="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="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="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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;YOUR_VITE_FIREBASE_API_KEY&lt;/span&gt;&lt;span class="dl"&gt;"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;YOUR_VITE_FIREBASE_AUTH_DOMAIN&lt;/span&gt;&lt;span class="dl"&gt;"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;YOUR_VITE_FIREBASE_PROJECT_ID&lt;/span&gt;&lt;span class="dl"&gt;"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;YOUR_VITE_FIREBASE_STORAGE_BUCKET&lt;/span&gt;&lt;span class="dl"&gt;"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;YOUR_VITE_FIREBASE_MESSAGING_SENDER_ID&lt;/span&gt;&lt;span class="dl"&gt;"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;YOUR_VITE_FIREBASE_APP_ID&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&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;app&lt;/span&gt; &lt;span class="o"&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="k"&gt;export&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="nx"&gt;app&lt;/span&gt;&lt;span class="p"&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;GenerateToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;permission&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&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;requestPermission&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;permission&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;granted&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;YOUR_VITE_FIREBASE_VAPID_KEY&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;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;Token generated&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 

 &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&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;permission&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;denied&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="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;User denied notification permission.&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="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;
  
  
  Setting Up the Service Worker
&lt;/h3&gt;

&lt;p&gt;Create a file named &lt;code&gt;firebase-messaging-sw.js&lt;/code&gt; inside your &lt;code&gt;public&lt;/code&gt; folder. This file handles push notifications when your app is closed or minimized. Since you cant import keys from &lt;code&gt;.env&lt;/code&gt; files here, you'll need to provide your keys directly or configure your build process to inject these keys. Here's what &lt;code&gt;firebase-messaging-sw.js&lt;/code&gt; should look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Import Firebase scriptsimportScripts("https://www.gstatic.com/firebasejs/8.10.0/firebase-app.js");&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="s2"&gt;https://www.gstatic.com/firebasejs/8.10.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 Firebase with your configuration &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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;YOUR_VITE_FIREBASE_API_KEY&lt;/span&gt;&lt;span class="dl"&gt;"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;YOUR_VITE_FIREBASE_AUTH_DOMAIN&lt;/span&gt;&lt;span class="dl"&gt;"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;YOUR_VITE_FIREBASE_PROJECT_ID&lt;/span&gt;&lt;span class="dl"&gt;"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;YOUR_VITE_FIREBASE_STORAGE_BUCKET&lt;/span&gt;&lt;span class="dl"&gt;"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;YOUR_VITE_FIREBASE_MESSAGING_SENDER_ID&lt;/span&gt;&lt;span class="dl"&gt;"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;YOUR_VITE_FIREBASE_APP_ID&lt;/span&gt;&lt;span class="dl"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;YOUR_VITE_FIREBASE_VAPID_KEY&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;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 an instance of 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="c1"&gt;// Handle background messages&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="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="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;
  
  
  Using the Token in Your App
&lt;/h3&gt;

&lt;p&gt;Import &lt;code&gt;GenerateToken&lt;/code&gt; in &lt;code&gt;App.tsx&lt;/code&gt; and call it inside &lt;code&gt;useEffect&lt;/code&gt; so the token is generated when your website loads. For showing notifications when the website is open (foreground notifications), import &lt;code&gt;onMessage&lt;/code&gt; and &lt;code&gt;messaging&lt;/code&gt; from &lt;code&gt;firebase/messaging&lt;/code&gt; and &lt;code&gt;firebase.ts&lt;/code&gt;, respectively. &lt;code&gt;onMessage&lt;/code&gt; takes two arguments: &lt;code&gt;messaging&lt;/code&gt; and a callback function.&lt;/p&gt;

&lt;p&gt;Here's a simple example using &lt;code&gt;react-hot-toast&lt;/code&gt; for notifications:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// App.tsx&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;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="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="k"&gt;import&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="s2"&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="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="s2"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./App.css&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;GenerateToken&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="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&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;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 

&lt;span class="c1"&gt;// other codes &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="nc"&gt;GenerateToken&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="nf"&gt;toast&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="o"&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;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* other code */&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&amp;gt; &lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="err"&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, console log the token and copy it. Then, follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;In the Firebase Console, scroll down and click "See all Firebase features."&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Find and click on "Cloud Messaging."&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click "Create your first campaign" &amp;gt; "Firebase Notification messages," then create.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fill out the form and click "Send test message."&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Paste the token where it says "Add an FCM registration token" and click the "+" sign.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click the "Test" button.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If your website is in the active tab, you'll see a toast notification; otherwise, you'll get a push notification. Make sure notifications are enabled in your system settings.&lt;/p&gt;

&lt;p&gt;Adding push notifications to your React app using Firebase Cloud Messaging is a powerful way to keep your users engaged and informed. By following the steps outlined in this guide, you can seamlessly integrate this feature into your application, ensuring that users receive timely updates whether they are actively using your app or not. With Firebase's robust and easy-to-use tools, setting up push notifications becomes a straightforward process, enhancing the overall user experience and keeping your audience connected. Happy coding!&lt;/p&gt;

</description>
      <category>typescriptpushnotifi</category>
      <category>firebasepushmessagin</category>
      <category>reactpushnotificatio</category>
      <category>react</category>
    </item>
    <item>
      <title>5 Basic VS Code Extensions You Must Use</title>
      <dc:creator>Samir Tiwari</dc:creator>
      <pubDate>Mon, 05 Aug 2024 07:53:16 +0000</pubDate>
      <link>https://dev.to/samirtiwari/5-basic-vs-code-extensions-you-must-use-5c55</link>
      <guid>https://dev.to/samirtiwari/5-basic-vs-code-extensions-you-must-use-5c55</guid>
      <description>&lt;p&gt;VS Code is one of the most popular IDEs that coders use these days. With VS Code, you can add various extensions to make your coding journey simpler and faster. There are tons of extensions available, but today, I'll discuss five basic VS Code extensions that can greatly enhance your coding experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Code Spell Checker
&lt;/h3&gt;

&lt;p&gt;When coding, there are many things to keep in mind, and spelling is one of them. While spelling might not seem like a big deal in coding (since you'll get errors if you misspell reserved words), it's important when pushing code to production. Misspelled text can raise red flags, so the Code Spell Checker extension is a great choice to help you catch those errors before they become problems.&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%2Fstreetsidesoftware.gallerycdn.vsassets.io%2Fextensions%2Fstreetsidesoftware%2Fcode-spell-checker%2F4.0.7%2F1722753063327%2FMicrosoft.VisualStudio.Services.Icons.Default" 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%2Fstreetsidesoftware.gallerycdn.vsassets.io%2Fextensions%2Fstreetsidesoftware%2Fcode-spell-checker%2F4.0.7%2F1722753063327%2FMicrosoft.VisualStudio.Services.Icons.Default" alt="Code Spell Checker" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Auto Rename Tag
&lt;/h3&gt;

&lt;p&gt;If you're a web developer, you'll often work with HTML tags. Sometimes, you might want to change tags for semantic reasons - for example, switching a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; to a &lt;code&gt;&amp;lt;footer&amp;gt;&lt;/code&gt;. Manually changing both the opening and closing tags can be a hassle, especially if you have to do it multiple times. Auto Rename Tag automatically updates the corresponding opening or closing tag when you rename one, saving you time and effort.&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%2Fformulahendry.gallerycdn.vsassets.io%2Fextensions%2Fformulahendry%2Fauto-rename-tag%2F0.1.10%2F1644319230173%2FMicrosoft.VisualStudio.Services.Icons.Default" 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%2Fformulahendry.gallerycdn.vsassets.io%2Fextensions%2Fformulahendry%2Fauto-rename-tag%2F0.1.10%2F1644319230173%2FMicrosoft.VisualStudio.Services.Icons.Default" alt="Auto Rename Tag" width="264" height="180"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. ES7 React/Redux/GraphQL/React-Native Snippets
&lt;/h3&gt;

&lt;p&gt;For React developers, this extension is a must-have. It helps you write React code faster by providing snippets of commonly used code. For instance, typing &lt;code&gt;rafce&lt;/code&gt; in a &lt;code&gt;.jsx&lt;/code&gt; or &lt;code&gt;.tsx&lt;/code&gt; file will generate a basic React component. This can significantly speed up your development process.&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%2Frodrigovallades.gallerycdn.vsassets.io%2Fextensions%2Frodrigovallades%2Fes7-react-js-snippets%2F1.9.3%2F1544731524156%2FMicrosoft.VisualStudio.Services.Icons.Default" 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%2Frodrigovallades.gallerycdn.vsassets.io%2Fextensions%2Frodrigovallades%2Fes7-react-js-snippets%2F1.9.3%2F1544731524156%2FMicrosoft.VisualStudio.Services.Icons.Default" alt="ES7 React/Redux/GraphQL/React-Native Snippets" width="800" height="565"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Prettier
&lt;/h3&gt;

&lt;p&gt;While Prettier doesn't directly help with coding, it formats your code, making it more readable and visually appealing. Writing code can get messy, and Prettier helps you keep it tidy. I personally recommend configuring Prettier to format your code automatically when you save it, so everything stays neat without extra effort.&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%2Fesbenp.gallerycdn.vsassets.io%2Fextensions%2Fesbenp%2Fprettier-vscode%2F10.4.0%2F1711025051911%2FMicrosoft.VisualStudio.Services.Icons.Default" 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%2Fesbenp.gallerycdn.vsassets.io%2Fextensions%2Fesbenp%2Fprettier-vscode%2F10.4.0%2F1711025051911%2FMicrosoft.VisualStudio.Services.Icons.Default" alt="Prettier" width="128" height="128"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Material Icon Theme
&lt;/h3&gt;

&lt;p&gt;Material Icon Theme doesn't directly assist with coding either, but it makes your project look more organized in VS Code by assigning icons to folders. It gives each folder an icon based on its name, helping you quickly identify folder contents and making your workspace visually appealing.&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%2Fpkief.gallerycdn.vsassets.io%2Fextensions%2Fpkief%2Fmaterial-icon-theme%2F5.8.0%2F1721852676544%2FMicrosoft.VisualStudio.Services.Icons.Default" 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%2Fpkief.gallerycdn.vsassets.io%2Fextensions%2Fpkief%2Fmaterial-icon-theme%2F5.8.0%2F1721852676544%2FMicrosoft.VisualStudio.Services.Icons.Default" alt="Material Icon Theme" width="500" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programmingblogs</category>
      <category>programmingtips</category>
      <category>vscodeextensions</category>
      <category>vscodetips</category>
    </item>
  </channel>
</rss>
