<?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>Forem: Dainy Jose</title>
    <description>The latest articles on Forem by Dainy Jose (@dainyjose).</description>
    <link>https://forem.com/dainyjose</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%2F2361642%2F2d2d706c-5407-43f9-a162-574bce781b78.png</url>
      <title>Forem: Dainy Jose</title>
      <link>https://forem.com/dainyjose</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/dainyjose"/>
    <language>en</language>
    <item>
      <title>Preparing Your iOS App for the Upcoming SDK Requirements (April 2026)</title>
      <dc:creator>Dainy Jose</dc:creator>
      <pubDate>Thu, 16 Apr 2026 12:10:57 +0000</pubDate>
      <link>https://forem.com/dainyjose/preparing-your-ios-app-for-the-upcoming-sdk-requirements-april-2026-3l7f</link>
      <guid>https://forem.com/dainyjose/preparing-your-ios-app-for-the-upcoming-sdk-requirements-april-2026-3l7f</guid>
      <description>&lt;p&gt;Apple has announced new minimum SDK requirements for App Store submissions starting &lt;strong&gt;April 28, 2026&lt;/strong&gt;. If you're working on an iOS app, it's time to plan your upgrade.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s Changing?
&lt;/h2&gt;

&lt;p&gt;All apps submitted to App Store Connect must be built with the latest SDK versions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;iOS / iPadOS → &lt;strong&gt;SDK 26 or later&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;tvOS → &lt;strong&gt;SDK 26 or later&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;visionOS → &lt;strong&gt;SDK 26 or later&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;watchOS → &lt;strong&gt;SDK 26 or later&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Required Upgrades
&lt;/h2&gt;

&lt;p&gt;To meet these requirements, ensure your development environment is updated:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;macOS → Version 26.4 (Tahoe)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Xcode → Version 26&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Common Issue After Upgrade
&lt;/h2&gt;

&lt;p&gt;After upgrading, you might encounter a build issue related to the &lt;strong&gt;&lt;code&gt;fmt&lt;/code&gt; library (v11.0.2)&lt;/strong&gt; when running the app on a physical device.&lt;/p&gt;

&lt;p&gt;This happens because the newer Apple Clang compiler in Xcode 26 has compatibility issues with &lt;code&gt;consteval&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Workaround Fix (Podfile Patch)
&lt;/h2&gt;

&lt;p&gt;Add the following snippet inside your existing &lt;code&gt;post_install do |installer|&lt;/code&gt; block in your &lt;strong&gt;Podfile&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Workaround for Xcode 26: newer Apple Clang breaks consteval in fmt 11.0.2&lt;/span&gt;
&lt;span class="c1"&gt;# Patch base.h to disable consteval since the header doesn't check for pre-defined FMT_USE_CONSTEVAL.&lt;/span&gt;

&lt;span class="n"&gt;fmt_base&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;installer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sandbox&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;root&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'fmt'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'include'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'fmt'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'base.h'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exist?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fmt_base&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fmt_base&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;include?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Xcode 26 workaround'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;patched&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gsub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="sr"&gt;/^(#elif defined\(__cpp_consteval\)\n#  define FMT_USE_CONSTEVAL) 1/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"// Xcode 26 workaround: disable consteval&lt;/span&gt;&lt;span class="se"&gt;\n\\&lt;/span&gt;&lt;span class="s2"&gt;1 0"&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;patched&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;
      &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;chmod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mo"&gt;0644&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fmt_base&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fmt_base&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;patched&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Final Steps
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Add the snippet to your &lt;code&gt;Podfile&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Run:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;   pod install
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Clean and rebuild your project&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Apple Announcement: &lt;a href="https://developer.apple.com/news/?id=ueeok6yw" rel="noopener noreferrer"&gt;https://developer.apple.com/news/?id=ueeok6yw&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Expo Issue Thread: &lt;a href="https://github.com/expo/expo/issues/44229" rel="noopener noreferrer"&gt;https://github.com/expo/expo/issues/44229&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Don’t wait until the deadline. Upgrade early to identify and fix compatibility issues in your dependencies.&lt;/p&gt;




&lt;p&gt;✍️ Written by &lt;a href="https://www.linkedin.com/in/dainyjose" rel="noopener noreferrer"&gt;&lt;strong&gt;Dainy Jose&lt;/strong&gt;&lt;/a&gt; — React Native Mobile Application Developer with 3+ years of experience building cross-platform mobile apps using &lt;strong&gt;React Native (Expo, TypeScript, Redux)&lt;/strong&gt;. &lt;br&gt;
Currently expanding backend knowledge through the &lt;strong&gt;MERN Stack (MongoDB, Express.js, React.js, Node.js)&lt;/strong&gt; to create more efficient, full-stack mobile experiences.&lt;/p&gt;

&lt;p&gt;💼 &lt;strong&gt;Tech Stack:&lt;/strong&gt; React Native · TypeScript · Redux · Expo · Firebase · Node.js · Express.js · MongoDB · REST API · JWT · Jest · Google Maps · Razorpay · PayU · Agile · SDLC · Git · Bitbucket · Jira &lt;/p&gt;

&lt;p&gt;📬 &lt;strong&gt;Connect with me&lt;/strong&gt;:&lt;br&gt;
🌐 &lt;a href="https://dainyjose.github.io/my-portfolio/" rel="noopener noreferrer"&gt;Portfolio&lt;/a&gt;&lt;br&gt;
🔗 &lt;a href="https://www.linkedin.com/in/dainyjose" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;br&gt;
💻 &lt;a href="https://github.com/dainyjose" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>xcode</category>
      <category>expo</category>
      <category>ios</category>
    </item>
    <item>
      <title>Implementing Firebase Crashlytics in React Native</title>
      <dc:creator>Dainy Jose</dc:creator>
      <pubDate>Sun, 15 Mar 2026 08:19:26 +0000</pubDate>
      <link>https://forem.com/dainyjose/implementing-firebase-crashlytics-in-react-native-12i3</link>
      <guid>https://forem.com/dainyjose/implementing-firebase-crashlytics-in-react-native-12i3</guid>
      <description>&lt;p&gt;&lt;strong&gt;Firebase Crashlytics&lt;/strong&gt; is a lightweight, real-time crash reporting tool that helps developers monitor, track, and fix app crashes. Integrating &lt;strong&gt;Crashlytics&lt;/strong&gt; in a React Native app improves app stability and ensures you can react quickly to issues in production.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before implementing Crashlytics, ensure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A React Native project (bare or Expo managed workflow).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Firebase project created in Firebase Console.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;@react-native-firebase/app&lt;/code&gt; and &lt;code&gt;@react-native-firebase/crashlytics&lt;/code&gt; installed (for bare workflow).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  2. Install Dependencies
&lt;/h2&gt;

&lt;p&gt;For React Native bare workflow, install Firebase packages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i @react-native-firebase/app @react-native-firebase/crashlytics
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For &lt;strong&gt;Expo managed workflow&lt;/strong&gt;, you can use the bare workflow or &lt;code&gt;expo-firebase-crashlytics&lt;/code&gt; (currently requires ejecting to bare workflow for full support).&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Configure Firebase in Your Project
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;iOS Setup&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Download &lt;code&gt;GoogleService-Info.plist&lt;/code&gt; from Firebase Console.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add it to &lt;code&gt;ios/YourAppName&lt;/code&gt; folder.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In Xcode, select your project → &lt;strong&gt;Build Phases → Copy Bundle Resources&lt;/strong&gt;, and ensure &lt;code&gt;GoogleService-Info.plist&lt;/code&gt; is included.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Android Setup&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Download &lt;code&gt;google-services.json&lt;/code&gt; from Firebase Console.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Place it under &lt;code&gt;android/app/&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify &lt;code&gt;android/build.gradle&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;buildscript &lt;span class="o"&gt;{&lt;/span&gt;
    dependencies &lt;span class="o"&gt;{&lt;/span&gt;
        classpath &lt;span class="s1"&gt;'com.google.gms:google-services:4.3.15'&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Modify &lt;code&gt;android/app/build.gradle&lt;/code&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apply plugin: &lt;span class="s1"&gt;'com.google.gms.google-services'&lt;/span&gt;

dependencies &lt;span class="o"&gt;{&lt;/span&gt;
    implementation platform&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'com.google.firebase:firebase-bom:32.1.0'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    implementation &lt;span class="s1"&gt;'com.google.firebase:firebase-crashlytics'&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  4. Initialize Firebase Crashlytics
&lt;/h2&gt;

&lt;p&gt;In your app’s entry file (&lt;code&gt;App.tsx&lt;/code&gt; or &lt;code&gt;index.js&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;import crashlytics from &lt;span class="s1"&gt;'@react-native-firebase/crashlytics'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import React, &lt;span class="o"&gt;{&lt;/span&gt; useEffect &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s1"&gt;'react'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import &lt;span class="o"&gt;{&lt;/span&gt; Button, View, Text &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s1"&gt;'react-native'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nb"&gt;export &lt;/span&gt;default &lt;span class="k"&gt;function &lt;/span&gt;App&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  useEffect&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    // Enable Crashlytics collection
    crashlytics&lt;span class="o"&gt;()&lt;/span&gt;.setCrashlyticsCollectionEnabled&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    // Log app start
    crashlytics&lt;span class="o"&gt;()&lt;/span&gt;.log&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'App mounted'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;, &lt;span class="o"&gt;[])&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  const testCrash &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    // This will trigger a &lt;span class="nb"&gt;test &lt;/span&gt;crash
    crashlytics&lt;span class="o"&gt;()&lt;/span&gt;.crash&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  const logCustomError &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    crashlytics&lt;span class="o"&gt;()&lt;/span&gt;.recordError&lt;span class="o"&gt;(&lt;/span&gt;new Error&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Custom handled error'&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;
    &amp;lt;View &lt;span class="nv"&gt;style&lt;/span&gt;&lt;span class="o"&gt;={{&lt;/span&gt; flex: 1, justifyContent: &lt;span class="s1"&gt;'center'&lt;/span&gt;, alignItems: &lt;span class="s1"&gt;'center'&lt;/span&gt; &lt;span class="o"&gt;}}&amp;gt;&lt;/span&gt;
      &amp;lt;Text&amp;gt;Firebase Crashlytics Demo&amp;lt;/Text&amp;gt;
      &amp;lt;Button &lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Test Crash"&lt;/span&gt; &lt;span class="nv"&gt;onPress&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;testCrash&lt;span class="o"&gt;}&lt;/span&gt; /&amp;gt;
      &amp;lt;Button &lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Log Custom Error"&lt;/span&gt; &lt;span class="nv"&gt;onPress&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;logCustomError&lt;span class="o"&gt;}&lt;/span&gt; /&amp;gt;
    &amp;lt;/View&amp;gt;
  &lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Enable crash reporting in production only&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;__DEV__&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    crashlytics&lt;span class="o"&gt;()&lt;/span&gt;.setCrashlyticsCollectionEnabled&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Log user-specific info&lt;/strong&gt; for better context:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;crashlytics&lt;span class="o"&gt;()&lt;/span&gt;.setUserId&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'USER_12345'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
crashlytics&lt;span class="o"&gt;()&lt;/span&gt;.setAttributes&lt;span class="o"&gt;({&lt;/span&gt; plan: &lt;span class="s1"&gt;'premium'&lt;/span&gt;, region: &lt;span class="s1"&gt;'IN'&lt;/span&gt; &lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use &lt;code&gt;recordError&lt;/code&gt; for handled errors&lt;/strong&gt;:&lt;br&gt;
Avoid throwing errors for non-critical events; instead, log them for debugging.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Test integration&lt;/strong&gt; using the &lt;code&gt;crash()&lt;/code&gt; method to ensure crashes are visible in Firebase Console.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  6. Optional: Handling Unhandled JS Exceptions
&lt;/h2&gt;

&lt;p&gt;React Native allows capturing unhandled JS exceptions and forwarding them to Crashlytics:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;import &lt;span class="o"&gt;{&lt;/span&gt; setJSExceptionHandler &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s1"&gt;'react-native-exception-handler'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import crashlytics from &lt;span class="s1"&gt;'@react-native-firebase/crashlytics'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

const errorHandler &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;error, isFatal&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  crashlytics&lt;span class="o"&gt;()&lt;/span&gt;.recordError&lt;span class="o"&gt;(&lt;/span&gt;error&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

setJSExceptionHandler&lt;span class="o"&gt;(&lt;/span&gt;errorHandler, &lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;/div&gt;






&lt;h2&gt;
  
  
  7. Monitoring &amp;amp; Analytics
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Go to Firebase Console → Crashlytics.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;View &lt;strong&gt;real-time crash reports&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Identify &lt;strong&gt;affected users&lt;/strong&gt;, &lt;strong&gt;device types&lt;/strong&gt;, &lt;strong&gt;OS versions&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Track errors by &lt;strong&gt;severity and frequency&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  8. Conclusion
&lt;/h2&gt;

&lt;p&gt;Integrating &lt;strong&gt;Firebase Crashlytics&lt;/strong&gt; in React Native is straightforward but highly valuable. It helps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Quickly identify and fix critical bugs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Improve app stability for real users.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Track both fatal crashes and handled exceptions.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




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

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://rnfirebase.io/crashlytics/usage" rel="noopener noreferrer"&gt;React Native Firebase Crashlytics&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://firebase.google.com/docs/crashlytics" rel="noopener noreferrer"&gt;Firebase Crashlytics Guide&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;✍️ Written by &lt;a href="https://www.linkedin.com/in/dainyjose" rel="noopener noreferrer"&gt;&lt;strong&gt;Dainy Jose&lt;/strong&gt;&lt;/a&gt; — React Native Mobile Application Developer with 3+ years of experience building cross-platform mobile apps using &lt;strong&gt;React Native (Expo, TypeScript, Redux)&lt;/strong&gt;. &lt;br&gt;
Currently expanding backend knowledge through the &lt;strong&gt;MERN Stack (MongoDB, Express.js, React.js, Node.js)&lt;/strong&gt; to create more efficient, full-stack mobile experiences.&lt;/p&gt;

&lt;p&gt;💼 &lt;strong&gt;Tech Stack:&lt;/strong&gt; React Native · TypeScript · Redux · Expo · Firebase · Node.js · Express.js · MongoDB · REST API · JWT · Jest · Google Maps · Razorpay · PayU · Agile · SDLC · Git · Bitbucket · Jira &lt;/p&gt;

&lt;p&gt;📬 &lt;strong&gt;Connect with me&lt;/strong&gt;:&lt;br&gt;
🌐 &lt;a href="https://dainyjose.github.io/my-portfolio/" rel="noopener noreferrer"&gt;Portfolio&lt;/a&gt;&lt;br&gt;
🔗 &lt;a href="https://www.linkedin.com/in/dainyjose" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;br&gt;
💻 &lt;a href="https://github.com/dainyjose" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>firebase</category>
    </item>
    <item>
      <title>Real-Time Location Tracking &amp; Live Route Updates in React Native</title>
      <dc:creator>Dainy Jose</dc:creator>
      <pubDate>Sun, 07 Dec 2025 15:56:04 +0000</pubDate>
      <link>https://forem.com/dainyjose/real-time-location-tracking-live-route-updates-in-react-native-4g15</link>
      <guid>https://forem.com/dainyjose/real-time-location-tracking-live-route-updates-in-react-native-4g15</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In &lt;a href="https://dev.to/dainyjose/showing-nearby-places-routes-in-react-native-maps-34b7"&gt;Part 3&lt;/a&gt; we explored how to show nearby places and draw routes.&lt;br&gt;
Now it’s time to go &lt;strong&gt;real-time&lt;/strong&gt; — tracking a moving user (or driver) on the map and updating the route live.&lt;/p&gt;

&lt;p&gt;We’ll use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;react-native-maps&lt;/strong&gt; → to display the route&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;expo-location&lt;/strong&gt; → to stream position updates&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;socket.io / API polling&lt;/strong&gt; → to broadcast position changes (optional for multi-user scenarios)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Step 1: Basic Setup
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx expo &lt;span class="nb"&gt;install &lt;/span&gt;react-native-maps expo-location
npm &lt;span class="nb"&gt;install &lt;/span&gt;socket.io-client
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Step 2: Watch the User’s Location Continuously
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;import React, &lt;span class="o"&gt;{&lt;/span&gt; useEffect, useState &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s2"&gt;"react"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import &lt;span class="o"&gt;{&lt;/span&gt; View, StyleSheet &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s2"&gt;"react-native"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import MapView, &lt;span class="o"&gt;{&lt;/span&gt; Marker, Polyline &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s2"&gt;"react-native-maps"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import &lt;span class="k"&gt;*&lt;/span&gt; as Location from &lt;span class="s2"&gt;"expo-location"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nb"&gt;export &lt;/span&gt;default &lt;span class="k"&gt;function &lt;/span&gt;LiveTrackingScreen&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  const &lt;span class="o"&gt;[&lt;/span&gt;region, setRegion] &lt;span class="o"&gt;=&lt;/span&gt; useState&amp;lt;any&amp;gt;&lt;span class="o"&gt;(&lt;/span&gt;null&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  const &lt;span class="o"&gt;[&lt;/span&gt;routeCoords, setRouteCoords] &lt;span class="o"&gt;=&lt;/span&gt; useState&amp;lt;any[]&amp;gt;&lt;span class="o"&gt;([])&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  useEffect&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;(&lt;/span&gt;async &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      const &lt;span class="o"&gt;{&lt;/span&gt; status &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; await Location.requestForegroundPermissionsAsync&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;status &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="s2"&gt;"granted"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      const loc &lt;span class="o"&gt;=&lt;/span&gt; await Location.getCurrentPositionAsync&lt;span class="o"&gt;({})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      const &lt;span class="o"&gt;{&lt;/span&gt; latitude, longitude &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; loc.coords&lt;span class="p"&gt;;&lt;/span&gt;

      setRegion&lt;span class="o"&gt;({&lt;/span&gt;
        latitude,
        longitude,
        latitudeDelta: 0.01,
        longitudeDelta: 0.01,
      &lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      const sub &lt;span class="o"&gt;=&lt;/span&gt; await Location.watchPositionAsync&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;{&lt;/span&gt;
          accuracy: Location.Accuracy.Highest,
          timeInterval: 3000,
          distanceInterval: 5, // update every 5 m
        &lt;span class="o"&gt;}&lt;/span&gt;,
        &lt;span class="o"&gt;(&lt;/span&gt;pos&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
          const &lt;span class="o"&gt;{&lt;/span&gt; latitude, longitude &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; pos.coords&lt;span class="p"&gt;;&lt;/span&gt;
          setRouteCoords&lt;span class="o"&gt;((&lt;/span&gt;prev&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;...prev, &lt;span class="o"&gt;{&lt;/span&gt; latitude, longitude &lt;span class="o"&gt;}])&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          setRegion&lt;span class="o"&gt;((&lt;/span&gt;r&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;({&lt;/span&gt; ...r, latitude, longitude &lt;span class="o"&gt;}))&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
      &lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; sub.remove&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;})()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;, &lt;span class="o"&gt;[])&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;region&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return &lt;/span&gt;null&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;
    &amp;lt;View &lt;span class="nv"&gt;style&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;styles.container&lt;span class="o"&gt;}&amp;gt;&lt;/span&gt;
      &amp;lt;MapView &lt;span class="nv"&gt;style&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;styles.map&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="nv"&gt;region&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;region&lt;span class="o"&gt;}&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;{&lt;/span&gt;routeCoords.length &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 0 &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;
          &amp;lt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &amp;lt;Polyline &lt;span class="nv"&gt;coordinates&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;routeCoords&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="nv"&gt;strokeWidth&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;4&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="nv"&gt;strokeColor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"#007AFF"&lt;/span&gt; /&amp;gt;
            &amp;lt;Marker &lt;span class="nv"&gt;coordinate&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;routeCoords[routeCoords.length - 1]&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"You"&lt;/span&gt; /&amp;gt;
          &amp;lt;/&amp;gt;
        &lt;span class="o"&gt;)}&lt;/span&gt;
      &amp;lt;/MapView&amp;gt;
    &amp;lt;/View&amp;gt;
  &lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

const styles &lt;span class="o"&gt;=&lt;/span&gt; StyleSheet.create&lt;span class="o"&gt;({&lt;/span&gt;
  container: &lt;span class="o"&gt;{&lt;/span&gt; flex: 1 &lt;span class="o"&gt;}&lt;/span&gt;,
  map: &lt;span class="o"&gt;{&lt;/span&gt; flex: 1 &lt;span class="o"&gt;}&lt;/span&gt;,
&lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  What this does:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Requests location permission.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Watches position every few seconds/meters.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Draws a live polyline trail of movement.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Step 3: (Optional) Share Location in Real Time
&lt;/h2&gt;

&lt;p&gt;To show another user’s movement (for example, a delivery partner), send location updates through a backend socket:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;import io from &lt;span class="s2"&gt;"socket.io-client"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
const socket &lt;span class="o"&gt;=&lt;/span&gt; io&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"https://your-backend-url.com"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

useEffect&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;routeCoords.length&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  const last &lt;span class="o"&gt;=&lt;/span&gt; routeCoords[routeCoords.length - 1]&lt;span class="p"&gt;;&lt;/span&gt;
  socket.emit&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"location:update"&lt;/span&gt;, last&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;, &lt;span class="o"&gt;[&lt;/span&gt;routeCoords]&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the receiver side:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;socket.on&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"location:update"&lt;/span&gt;, &lt;span class="o"&gt;(&lt;/span&gt;coords&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  setDriverLocation&lt;span class="o"&gt;(&lt;/span&gt;coords&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&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’ll then render &lt;code&gt;driverLocation&lt;/code&gt; as a marker that updates instantly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Smooth Marker Animation
&lt;/h2&gt;

&lt;p&gt;For smoother UX, use &lt;strong&gt;react-native-maps-animated-marker&lt;/strong&gt; or Animated API to interpolate coordinates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;// pseudo
Animated.timing&lt;span class="o"&gt;(&lt;/span&gt;markerRef, &lt;span class="o"&gt;{&lt;/span&gt;
  toValue: new AnimatedRegion&lt;span class="o"&gt;({&lt;/span&gt; latitude, longitude &lt;span class="o"&gt;})&lt;/span&gt;,
  useNativeDriver: &lt;span class="nb"&gt;false&lt;/span&gt;,
&lt;span class="o"&gt;})&lt;/span&gt;.start&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a fluid moving-car effect rather than jumpy updates.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;And that’s it — you’ve built a real-time location tracker with live route updates.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key takeaways:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Use &lt;code&gt;watchPositionAsync&lt;/code&gt; for continuous tracking.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Store coordinates to visualize movement with polylines.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Integrate sockets for multi-user real-time sharing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Animate markers for smooth transitions.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;✍️ Written by &lt;a href="https://www.linkedin.com/in/dainyjose" rel="noopener noreferrer"&gt;&lt;strong&gt;Dainy Jose&lt;/strong&gt;&lt;/a&gt; — React Native Mobile Application Developer with 3+ years of experience building cross-platform mobile apps using &lt;strong&gt;React Native (Expo, TypeScript, Redux)&lt;/strong&gt;. &lt;br&gt;
Currently expanding backend knowledge through the &lt;strong&gt;MERN Stack (MongoDB, Express.js, React.js, Node.js)&lt;/strong&gt; to create more efficient, full-stack mobile experiences.&lt;/p&gt;

&lt;p&gt;💼 &lt;strong&gt;Tech Stack:&lt;/strong&gt; React Native · TypeScript · Redux · Expo · Firebase · Node.js · Express.js · MongoDB · REST API · JWT · Jest · Google Maps · Razorpay · PayU · Agile · SDLC · Git · Bitbucket · Jira &lt;/p&gt;

&lt;p&gt;📬 &lt;strong&gt;Connect with me&lt;/strong&gt;:&lt;br&gt;
🌐 &lt;a href="https://dainyjose.github.io/my-portfolio/" rel="noopener noreferrer"&gt;Portfolio&lt;/a&gt;&lt;br&gt;
🔗 &lt;a href="https://www.linkedin.com/in/dainyjose" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;br&gt;
💻 &lt;a href="https://github.com/dainyjose" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>mobile</category>
      <category>development</category>
    </item>
    <item>
      <title>Showing Nearby Places &amp; Routes in React Native Maps</title>
      <dc:creator>Dainy Jose</dc:creator>
      <pubDate>Mon, 01 Dec 2025 02:18:54 +0000</pubDate>
      <link>https://forem.com/dainyjose/showing-nearby-places-routes-in-react-native-maps-34b7</link>
      <guid>https://forem.com/dainyjose/showing-nearby-places-routes-in-react-native-maps-34b7</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In &lt;a href="https://dev.to/dainyjose/seamless-map-integration-in-react-native-a-complete-guide-29o7"&gt;Part 1&lt;/a&gt; we integrated maps into React Native, and in &lt;a href="https://dev.to/dainyjose/building-a-location-picker-in-react-native-maps-with-draggable-marker-address-lookup-1d00"&gt;Part 2&lt;/a&gt; we built a location picker.&lt;/p&gt;

&lt;p&gt;Now, let’s make it smarter — by showing &lt;strong&gt;nearby places&lt;/strong&gt; (like restaurants or stores) and drawing &lt;strong&gt;routes&lt;/strong&gt; between two points.&lt;/p&gt;

&lt;p&gt;We’ll use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;react-native-maps&lt;/strong&gt; for rendering&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Google Places API&lt;/strong&gt; for nearby results&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Google Directions API&lt;/strong&gt; for routing&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 1: Enable Required APIs
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Go to your &lt;a href="https://console.cloud.google.com/" rel="noopener noreferrer"&gt;Google Cloud Console&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enable:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Maps SDK for Android / iOS&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Places API&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Directions API&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Create or reuse an API key and restrict it to your app’s bundle ID or SHA-1.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 2: Basic Setup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx expo &lt;span class="nb"&gt;install &lt;/span&gt;react-native-maps expo-location
npm &lt;span class="nb"&gt;install &lt;/span&gt;axios
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Fetch Nearby Places
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;import React, &lt;span class="o"&gt;{&lt;/span&gt; useEffect, useState &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s1"&gt;'react'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import &lt;span class="o"&gt;{&lt;/span&gt; View, StyleSheet, Text &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s1"&gt;'react-native'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import MapView, &lt;span class="o"&gt;{&lt;/span&gt; Marker, Polyline &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s1"&gt;'react-native-maps'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import &lt;span class="k"&gt;*&lt;/span&gt; as Location from &lt;span class="s1"&gt;'expo-location'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import axios from &lt;span class="s1"&gt;'axios'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

const GOOGLE_API_KEY &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'YOUR_GOOGLE_MAPS_API_KEY'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nb"&gt;export &lt;/span&gt;default &lt;span class="k"&gt;function &lt;/span&gt;NearbyMap&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  const &lt;span class="o"&gt;[&lt;/span&gt;region, setRegion] &lt;span class="o"&gt;=&lt;/span&gt; useState&amp;lt;any&amp;gt;&lt;span class="o"&gt;(&lt;/span&gt;null&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  const &lt;span class="o"&gt;[&lt;/span&gt;places, setPlaces] &lt;span class="o"&gt;=&lt;/span&gt; useState&amp;lt;any[]&amp;gt;&lt;span class="o"&gt;([])&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  const &lt;span class="o"&gt;[&lt;/span&gt;routeCoords, setRouteCoords] &lt;span class="o"&gt;=&lt;/span&gt; useState&amp;lt;any[]&amp;gt;&lt;span class="o"&gt;([])&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  useEffect&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;(&lt;/span&gt;async &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      const &lt;span class="o"&gt;{&lt;/span&gt; status &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; await Location.requestForegroundPermissionsAsync&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;status &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="s1"&gt;'granted'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      const pos &lt;span class="o"&gt;=&lt;/span&gt; await Location.getCurrentPositionAsync&lt;span class="o"&gt;({})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      const &lt;span class="o"&gt;{&lt;/span&gt; latitude, longitude &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; pos.coords&lt;span class="p"&gt;;&lt;/span&gt;
      setRegion&lt;span class="o"&gt;({&lt;/span&gt;
        latitude,
        longitude,
        latitudeDelta: 0.01,
        longitudeDelta: 0.01,
      &lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      fetchNearby&lt;span class="o"&gt;(&lt;/span&gt;latitude, longitude&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;})()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;, &lt;span class="o"&gt;[])&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  const fetchNearby &lt;span class="o"&gt;=&lt;/span&gt; async &lt;span class="o"&gt;(&lt;/span&gt;lat: number, lng: number&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    const url &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sb"&gt;`&lt;/span&gt;https://maps.googleapis.com/maps/api/place/nearbysearch/json?location&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;lat&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;,&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;lng&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&amp;amp;radius&lt;span class="o"&gt;=&lt;/span&gt;1000&amp;amp;type&lt;span class="o"&gt;=&lt;/span&gt;restaurant&amp;amp;key&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;GOOGLE_API_KEY&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    const &lt;span class="o"&gt;{&lt;/span&gt; data &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; await axios.get&lt;span class="o"&gt;(&lt;/span&gt;url&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    setPlaces&lt;span class="o"&gt;(&lt;/span&gt;data.results&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  const drawRoute &lt;span class="o"&gt;=&lt;/span&gt; async &lt;span class="o"&gt;(&lt;/span&gt;destLat: number, destLng: number&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    const url &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sb"&gt;`&lt;/span&gt;https://maps.googleapis.com/maps/api/directions/json?origin&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;region&lt;/span&gt;&lt;span class="p"&gt;.latitude&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;,&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;region&lt;/span&gt;&lt;span class="p"&gt;.longitude&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&amp;amp;destination&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;destLat&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;,&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;destLng&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&amp;amp;key&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;GOOGLE_API_KEY&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    const &lt;span class="o"&gt;{&lt;/span&gt; data &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; await axios.get&lt;span class="o"&gt;(&lt;/span&gt;url&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    const points &lt;span class="o"&gt;=&lt;/span&gt; decode&lt;span class="o"&gt;(&lt;/span&gt;data.routes[0].overview_polyline.points&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    setRouteCoords&lt;span class="o"&gt;(&lt;/span&gt;points&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  // Polyline decoding helper
  const decode &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;t: string&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;let &lt;/span&gt;points &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;let &lt;/span&gt;step &lt;span class="o"&gt;=&lt;/span&gt; 0, lat &lt;span class="o"&gt;=&lt;/span&gt; 0, lng &lt;span class="o"&gt;=&lt;/span&gt; 0&lt;span class="p"&gt;;&lt;/span&gt; step &amp;lt; t.length&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="nb"&gt;let &lt;/span&gt;b, &lt;span class="nb"&gt;shift&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 0, result &lt;span class="o"&gt;=&lt;/span&gt; 0&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; b &lt;span class="o"&gt;=&lt;/span&gt; t.charCodeAt&lt;span class="o"&gt;(&lt;/span&gt;step++&lt;span class="o"&gt;)&lt;/span&gt; - 63&lt;span class="p"&gt;;&lt;/span&gt; result |&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;b &amp;amp; 31&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;shift&lt;/span&gt;&lt;span class="sh"&gt;; shift += 5; } while (b &amp;gt;= 32);
      lat += (result &amp;amp; 1) ? ~(result &amp;gt;&amp;gt; 1) : (result &amp;gt;&amp;gt; 1);
      shift = result = 0;
      do { b = t.charCodeAt(step++) - 63; result |= (b &amp;amp; 31) &amp;lt;&amp;lt; shift; shift += 5; } while (b &amp;gt;= 32);
      lng += (result &amp;amp; 1) ? ~(result &amp;gt;&amp;gt; 1) : (result &amp;gt;&amp;gt; 1);
      points.push({ latitude: lat / 1e5, longitude: lng / 1e5 });
    }
    return points;
  };

  if (!region) return &amp;lt;Text&amp;gt;Loading map...&amp;lt;/Text&amp;gt;;

  return (
    &amp;lt;View style={styles.container}&amp;gt;
      &amp;lt;MapView style={styles.map} region={region}&amp;gt;
        {places.map((p, i) =&amp;gt; (
          &amp;lt;Marker
            key={i}
            coordinate={{
              latitude: p.geometry.location.lat,
              longitude: p.geometry.location.lng,
            }}
            title={p.name}
            onPress={() =&amp;gt; drawRoute(p.geometry.location.lat, p.geometry.location.lng)}
          /&amp;gt;
        ))}
        {routeCoords.length &amp;gt; 0 &amp;amp;&amp;amp; (
          &amp;lt;Polyline coordinates={routeCoords} strokeWidth={4} strokeColor="#007AFF" /&amp;gt;
        )}
      &amp;lt;/MapView&amp;gt;
    &amp;lt;/View&amp;gt;
  );
}

const styles = StyleSheet.create({
  container: { flex: 1 },
  map: { flex: 1 },
});
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What this does&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Detects your location&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fetches nearby restaurants within 1 km&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Draws a route when you tap a marker&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 4: Optimize UX
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Use a bottom sheet to show place details.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add filters for different types (&lt;code&gt;cafe&lt;/code&gt;, &lt;code&gt;hospital&lt;/code&gt;, etc.).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cache responses for smoother panning.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;With just a few APIs, you’ve now added &lt;strong&gt;intelligent location awareness&lt;/strong&gt; to your app — users can view nearby places and get directions instantly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key takeaways&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Always restrict your API key.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Decode Google’s polyline for routes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Combine Places + Directions APIs for real-time navigation features.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What’s Next
&lt;/h3&gt;

&lt;p&gt;Next, I’ll explore “Building Real-Time Location Tracking in React Native” — ideal for delivery or event apps.&lt;/p&gt;




&lt;p&gt;✍️ Written by &lt;a href="https://www.linkedin.com/in/dainyjose" rel="noopener noreferrer"&gt;&lt;strong&gt;Dainy Jose&lt;/strong&gt;&lt;/a&gt; — React Native Mobile Application Developer with 3+ years of experience building cross-platform mobile apps using &lt;strong&gt;React Native (Expo, TypeScript, Redux)&lt;/strong&gt;. &lt;br&gt;
Currently expanding backend knowledge through the &lt;strong&gt;MERN Stack (MongoDB, Express.js, React.js, Node.js)&lt;/strong&gt; to create more efficient, full-stack mobile experiences.&lt;/p&gt;

&lt;p&gt;💼 &lt;strong&gt;Tech Stack:&lt;/strong&gt; React Native · TypeScript · Redux · Expo · Firebase · Node.js · Express.js · MongoDB · REST API · JWT · Jest · Google Maps · Razorpay · PayU · Agile · SDLC · Git · Bitbucket · Jira &lt;/p&gt;

&lt;p&gt;📬 &lt;strong&gt;Connect with me&lt;/strong&gt;:&lt;br&gt;
🌐 &lt;a href="https://dainyjose.github.io/my-portfolio/" rel="noopener noreferrer"&gt;Portfolio&lt;/a&gt;&lt;br&gt;
🔗 &lt;a href="https://www.linkedin.com/in/dainyjose" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;br&gt;
💻 &lt;a href="https://github.com/dainyjose" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>map</category>
      <category>googlemapsapi</category>
    </item>
    <item>
      <title>Building a Location Picker in React Native Maps (with Draggable Marker &amp; Address Lookup)</title>
      <dc:creator>Dainy Jose</dc:creator>
      <pubDate>Sun, 23 Nov 2025 17:59:06 +0000</pubDate>
      <link>https://forem.com/dainyjose/building-a-location-picker-in-react-native-maps-with-draggable-marker-address-lookup-1d00</link>
      <guid>https://forem.com/dainyjose/building-a-location-picker-in-react-native-maps-with-draggable-marker-address-lookup-1d00</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In &lt;a href="https://dev.to/dainyjose/seamless-map-integration-in-react-native-a-complete-guide-29o7"&gt;my previous post&lt;/a&gt;, I covered how to integrate Google Maps and display the user’s live location.&lt;/p&gt;

&lt;p&gt;Now let’s take it one step further — by creating a &lt;strong&gt;location picker&lt;/strong&gt; where users can drag a marker or move the map to select an address. This feature is perfect for checkout pages, delivery address setup, or event creation screens.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Setup
&lt;/h2&gt;

&lt;p&gt;We’ll continue using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx expo &lt;span class="nb"&gt;install &lt;/span&gt;react-native-maps expo-location
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Optional (for reverse geocoding):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx expo &lt;span class="nb"&gt;install &lt;/span&gt;expo-location
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Display the Map with a Draggable Marker
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;import React, &lt;span class="o"&gt;{&lt;/span&gt; useState, useEffect &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s1"&gt;'react'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import &lt;span class="o"&gt;{&lt;/span&gt; View, Text, StyleSheet &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s1"&gt;'react-native'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import MapView, &lt;span class="o"&gt;{&lt;/span&gt; Marker &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s1"&gt;'react-native-maps'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import &lt;span class="k"&gt;*&lt;/span&gt; as Location from &lt;span class="s1"&gt;'expo-location'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nb"&gt;export &lt;/span&gt;default &lt;span class="k"&gt;function &lt;/span&gt;LocationPicker&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  const &lt;span class="o"&gt;[&lt;/span&gt;region, setRegion] &lt;span class="o"&gt;=&lt;/span&gt; useState&lt;span class="o"&gt;(&lt;/span&gt;null&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  const &lt;span class="o"&gt;[&lt;/span&gt;address, setAddress] &lt;span class="o"&gt;=&lt;/span&gt; useState&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  useEffect&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;(&lt;/span&gt;async &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      const &lt;span class="o"&gt;{&lt;/span&gt; status &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; await Location.requestForegroundPermissionsAsync&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;status &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="s1"&gt;'granted'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      const current &lt;span class="o"&gt;=&lt;/span&gt; await Location.getCurrentPositionAsync&lt;span class="o"&gt;({})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      const &lt;span class="o"&gt;{&lt;/span&gt; latitude, longitude &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; current.coords&lt;span class="p"&gt;;&lt;/span&gt;
      setRegion&lt;span class="o"&gt;({&lt;/span&gt;
        latitude,
        longitude,
        latitudeDelta: 0.01,
        longitudeDelta: 0.01,
      &lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      getAddress&lt;span class="o"&gt;(&lt;/span&gt;latitude, longitude&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;})()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;, &lt;span class="o"&gt;[])&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  const getAddress &lt;span class="o"&gt;=&lt;/span&gt; async &lt;span class="o"&gt;(&lt;/span&gt;lat: number, lng: number&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    const &lt;span class="o"&gt;[&lt;/span&gt;place] &lt;span class="o"&gt;=&lt;/span&gt; await Location.reverseGeocodeAsync&lt;span class="o"&gt;({&lt;/span&gt; latitude: lat, longitude: lng &lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;place&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      setAddress&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;place&lt;/span&gt;&lt;span class="p"&gt;.name || &lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;, &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;place&lt;/span&gt;&lt;span class="p"&gt;.city || &lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;, &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;place&lt;/span&gt;&lt;span class="p"&gt;.region || &lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  const onMarkerDragEnd &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;e: any&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    const &lt;span class="o"&gt;{&lt;/span&gt; latitude, longitude &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; e.nativeEvent.coordinate&lt;span class="p"&gt;;&lt;/span&gt;
    setRegion&lt;span class="o"&gt;({&lt;/span&gt; ...region, latitude, longitude &lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    getAddress&lt;span class="o"&gt;(&lt;/span&gt;latitude, longitude&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;region&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &amp;lt;Text&amp;gt;Loading map...&amp;lt;/Text&amp;gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;
    &amp;lt;View &lt;span class="nv"&gt;style&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;styles.container&lt;span class="o"&gt;}&amp;gt;&lt;/span&gt;
      &amp;lt;MapView &lt;span class="nv"&gt;style&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;styles.map&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="nv"&gt;region&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;region&lt;span class="o"&gt;}&amp;gt;&lt;/span&gt;
        &amp;lt;Marker
          &lt;span class="nv"&gt;coordinate&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;region&lt;span class="o"&gt;}&lt;/span&gt;
          draggable
          &lt;span class="nv"&gt;onDragEnd&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;onMarkerDragEnd&lt;span class="o"&gt;}&lt;/span&gt;
          &lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Selected Location"&lt;/span&gt;
        /&amp;gt;
      &amp;lt;/MapView&amp;gt;
      &amp;lt;View &lt;span class="nv"&gt;style&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;styles.infoBox&lt;span class="o"&gt;}&amp;gt;&lt;/span&gt;
        &amp;lt;Text &lt;span class="nv"&gt;style&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;styles.label&lt;span class="o"&gt;}&amp;gt;&lt;/span&gt;Selected Address:&amp;lt;/Text&amp;gt;
        &amp;lt;Text &lt;span class="nv"&gt;style&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;styles.address&lt;span class="o"&gt;}&amp;gt;{&lt;/span&gt;address &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s1"&gt;'Move marker to select'&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;&amp;lt;/Text&amp;gt;
      &amp;lt;/View&amp;gt;
    &amp;lt;/View&amp;gt;
  &lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

const styles &lt;span class="o"&gt;=&lt;/span&gt; StyleSheet.create&lt;span class="o"&gt;({&lt;/span&gt;
  container: &lt;span class="o"&gt;{&lt;/span&gt; flex: 1 &lt;span class="o"&gt;}&lt;/span&gt;,
  map: &lt;span class="o"&gt;{&lt;/span&gt; flex: 1 &lt;span class="o"&gt;}&lt;/span&gt;,
  infoBox: &lt;span class="o"&gt;{&lt;/span&gt;
    position: &lt;span class="s1"&gt;'absolute'&lt;/span&gt;,
    bottom: 40,
    left: 20,
    right: 20,
    backgroundColor: &lt;span class="s1"&gt;'#fff'&lt;/span&gt;,
    borderRadius: 12,
    padding: 10,
    shadowColor: &lt;span class="s1"&gt;'#000'&lt;/span&gt;,
    shadowOpacity: 0.1,
    shadowRadius: 6,
  &lt;span class="o"&gt;}&lt;/span&gt;,
  label: &lt;span class="o"&gt;{&lt;/span&gt; fontWeight: &lt;span class="s1"&gt;'600'&lt;/span&gt;, marginBottom: 4 &lt;span class="o"&gt;}&lt;/span&gt;,
  address: &lt;span class="o"&gt;{&lt;/span&gt; fontSize: 14, color: &lt;span class="s1"&gt;'#333'&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;,
&lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What this does:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Displays your current location.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Lets you &lt;strong&gt;drag the marker&lt;/strong&gt; to a new position.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Updates the address in real time.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 3: Use Map Pan Instead of Marker Drag
&lt;/h2&gt;

&lt;p&gt;If you prefer to &lt;strong&gt;keep the marker fixed&lt;/strong&gt; and move the map instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&amp;lt;MapView
  &lt;span class="nv"&gt;style&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;styles.map&lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="nv"&gt;region&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;region&lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="nv"&gt;onRegionChangeComplete&lt;/span&gt;&lt;span class="o"&gt;={(&lt;/span&gt;r&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    setRegion&lt;span class="o"&gt;(&lt;/span&gt;r&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    getAddress&lt;span class="o"&gt;(&lt;/span&gt;r.latitude, r.longitude&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}}&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &amp;lt;Marker &lt;span class="nv"&gt;coordinate&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;region&lt;span class="o"&gt;}&lt;/span&gt; /&amp;gt;
&amp;lt;/MapView&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This feels more natural for UX — the marker stays centered while the user pans the map.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Save the Selected Location
&lt;/h2&gt;

&lt;p&gt;Once the user confirms the spot, send it back to your backend or state management:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&amp;lt;Button
  &lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Confirm Location"&lt;/span&gt;
  &lt;span class="nv"&gt;onPress&lt;/span&gt;&lt;span class="o"&gt;={()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; console.log&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Saved location:'&lt;/span&gt;, region, address&lt;span class="o"&gt;)}&lt;/span&gt;
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;And that’s it! You’ve now built a fully functional location picker in React Native using &lt;code&gt;react-native-maps&lt;/code&gt; and Expo Location.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Takeaways:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Always handle permissions before rendering the map.&lt;/p&gt;

&lt;p&gt;Use reverse geocoding to get human-readable addresses.&lt;/p&gt;

&lt;p&gt;For better UX, fix the marker and move the map instead of dragging.&lt;/p&gt;

&lt;p&gt;🔗 Next Up&lt;/p&gt;

&lt;p&gt;In my next post, I’ll explore how to show nearby places and routes using Google Maps APIs in React Native. Stay tuned!&lt;/p&gt;




&lt;p&gt;✍️ Written by &lt;a href="https://www.linkedin.com/in/dainyjose" rel="noopener noreferrer"&gt;&lt;strong&gt;Dainy Jose&lt;/strong&gt;&lt;/a&gt; — React Native Mobile Application Developer with 3+ years of experience building cross-platform mobile apps using &lt;strong&gt;React Native (Expo, TypeScript, Redux)&lt;/strong&gt;. &lt;br&gt;
Currently expanding backend knowledge through the &lt;strong&gt;MERN Stack (MongoDB, Express.js, React.js, Node.js)&lt;/strong&gt; to create more efficient, full-stack mobile experiences.&lt;/p&gt;

&lt;p&gt;💼 &lt;strong&gt;Tech Stack:&lt;/strong&gt; React Native · TypeScript · Redux · Expo · Firebase · Node.js · Express.js · MongoDB · REST API · JWT · Jest · Google Maps · Razorpay · PayU · Agile · SDLC · Git · Bitbucket · Jira &lt;/p&gt;

&lt;p&gt;📬 &lt;strong&gt;Connect with me&lt;/strong&gt;:&lt;br&gt;
🌐 &lt;a href="https://dainyjose.github.io/my-portfolio/" rel="noopener noreferrer"&gt;Portfolio&lt;/a&gt;&lt;br&gt;
🔗 &lt;a href="https://www.linkedin.com/in/dainyjose" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;br&gt;
💻 &lt;a href="https://github.com/dainyjose" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>map</category>
      <category>mobile</category>
      <category>development</category>
    </item>
    <item>
      <title>Seamless Map Integration in React Native: A Complete Guide</title>
      <dc:creator>Dainy Jose</dc:creator>
      <pubDate>Sun, 16 Nov 2025 10:14:36 +0000</pubDate>
      <link>https://forem.com/dainyjose/seamless-map-integration-in-react-native-a-complete-guide-29o7</link>
      <guid>https://forem.com/dainyjose/seamless-map-integration-in-react-native-a-complete-guide-29o7</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Integrating maps into a React Native app sounds simple — until you face platform-specific quirks, location permission issues, and crashes (especially on Android).&lt;/p&gt;

&lt;p&gt;In this post, I’ll walk you through how I integrated &lt;strong&gt;Google Maps&lt;/strong&gt; into my React Native app using the &lt;strong&gt;Expo Bare Workflow&lt;/strong&gt;, including handling permissions, displaying the user’s live location, and fixing common pitfalls like Android crashes when using &lt;code&gt;showsUserLocation&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Setting Up the Map
&lt;/h3&gt;

&lt;p&gt;If you’re using Expo (Bare or Managed), the easiest way to start is with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx expo &lt;span class="nb"&gt;install &lt;/span&gt;react-native-maps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, import the component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;import MapView, &lt;span class="o"&gt;{&lt;/span&gt; Marker &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s1"&gt;'react-native-maps'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import &lt;span class="o"&gt;{&lt;/span&gt; StyleSheet, View &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s1"&gt;'react-native'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


Render a simple map:

&lt;span class="nb"&gt;export &lt;/span&gt;default &lt;span class="k"&gt;function &lt;/span&gt;MapScreen&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;
    &amp;lt;View &lt;span class="nv"&gt;style&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;styles.container&lt;span class="o"&gt;}&amp;gt;&lt;/span&gt;
      &amp;lt;MapView
        &lt;span class="nv"&gt;style&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;styles.map&lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="nv"&gt;initialRegion&lt;/span&gt;&lt;span class="o"&gt;={{&lt;/span&gt;
          latitude: 37.78825,
          longitude: &lt;span class="nt"&gt;-122&lt;/span&gt;.4324,
          latitudeDelta: 0.0922,
          longitudeDelta: 0.0421,
        &lt;span class="o"&gt;}}&lt;/span&gt;
      /&amp;gt;
    &amp;lt;/View&amp;gt;
  &lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

const styles &lt;span class="o"&gt;=&lt;/span&gt; StyleSheet.create&lt;span class="o"&gt;({&lt;/span&gt;
  container: &lt;span class="o"&gt;{&lt;/span&gt; flex: 1 &lt;span class="o"&gt;}&lt;/span&gt;,
  map: &lt;span class="o"&gt;{&lt;/span&gt; width: &lt;span class="s1"&gt;'100%'&lt;/span&gt;, height: &lt;span class="s1"&gt;'100%'&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;,
&lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s your base map ready.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Request Location Permissions
&lt;/h3&gt;

&lt;p&gt;To show the user’s live location, install Expo Location:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx expo &lt;span class="nb"&gt;install &lt;/span&gt;expo-location
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then request permission before displaying the map:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;import &lt;span class="k"&gt;*&lt;/span&gt; as Location from &lt;span class="s1"&gt;'expo-location'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import &lt;span class="o"&gt;{&lt;/span&gt; useEffect, useState &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s1"&gt;'react'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

const &lt;span class="o"&gt;[&lt;/span&gt;location, setLocation] &lt;span class="o"&gt;=&lt;/span&gt; useState&lt;span class="o"&gt;(&lt;/span&gt;null&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

useEffect&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="o"&gt;(&lt;/span&gt;async &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;let&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; status &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; await Location.requestForegroundPermissionsAsync&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;status &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="s1"&gt;'granted'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      console.warn&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Permission denied'&lt;/span&gt;&lt;span class="o"&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;}&lt;/span&gt;

    &lt;span class="nb"&gt;let &lt;/span&gt;current &lt;span class="o"&gt;=&lt;/span&gt; await Location.getCurrentPositionAsync&lt;span class="o"&gt;({})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    setLocation&lt;span class="o"&gt;(&lt;/span&gt;current.coords&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;})()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;, &lt;span class="o"&gt;[])&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Display User’s Current Location
&lt;/h3&gt;

&lt;p&gt;Once permission is granted, set your map’s region dynamically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&amp;lt;MapView
  &lt;span class="nv"&gt;style&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;styles.map&lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="nv"&gt;region&lt;/span&gt;&lt;span class="o"&gt;={{&lt;/span&gt;
    latitude: location?.latitude &lt;span class="o"&gt;||&lt;/span&gt; 37.78825,
    longitude: location?.longitude &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nt"&gt;-122&lt;/span&gt;.4324,
    latitudeDelta: 0.01,
    longitudeDelta: 0.01,
  &lt;span class="o"&gt;}}&lt;/span&gt;
  &lt;span class="nv"&gt;showsUserLocation&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="nv"&gt;showsMyLocationButton&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Fix Android Crash with showsUserLocation
&lt;/h3&gt;

&lt;p&gt;If you notice your &lt;strong&gt;app crashes on Android&lt;/strong&gt; when &lt;code&gt;showsUserLocation={true}&lt;/code&gt;, it’s usually because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The location permission isn’t granted before rendering the map, or&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The native module initialization fails due to race conditions.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Fix:
&lt;/h3&gt;

&lt;p&gt;Wrap your &lt;code&gt;&amp;lt;MapView /&amp;gt;&lt;/code&gt; inside a condition that ensures &lt;code&gt;location&lt;/code&gt; is loaded first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;{&lt;/span&gt;location &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;
  &amp;lt;MapView
    &lt;span class="nv"&gt;style&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;styles.map&lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="nv"&gt;showsUserLocation&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="nv"&gt;region&lt;/span&gt;&lt;span class="o"&gt;={{&lt;/span&gt;
      latitude: location.latitude,
      longitude: location.longitude,
      latitudeDelta: 0.01,
      longitudeDelta: 0.01,
    &lt;span class="o"&gt;}}&lt;/span&gt;
  /&amp;gt;
&lt;span class="o"&gt;)}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This small conditional check prevents the crash on Android and ensures the map renders only after location access.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Adding Markers
&lt;/h3&gt;

&lt;p&gt;You can easily add markers for points of interest:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&amp;lt;Marker
  &lt;span class="nv"&gt;coordinate&lt;/span&gt;&lt;span class="o"&gt;={{&lt;/span&gt;
    latitude: 37.78825,
    longitude: &lt;span class="nt"&gt;-122&lt;/span&gt;.4324,
  &lt;span class="o"&gt;}}&lt;/span&gt;
  &lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"My Favorite Spot"&lt;/span&gt;
  &lt;span class="nv"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"This is where I test map features."&lt;/span&gt;
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can even loop through API data to dynamically render multiple markers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bonus: Custom Map Styling
&lt;/h3&gt;

&lt;p&gt;You can use Google Map styles to match your app’s branding:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;const customMapStyle &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;
  &lt;span class="o"&gt;{&lt;/span&gt;
    elementType: &lt;span class="s1"&gt;'geometry'&lt;/span&gt;,
    stylers: &lt;span class="o"&gt;[{&lt;/span&gt; color: &lt;span class="s1"&gt;'#212121'&lt;/span&gt; &lt;span class="o"&gt;}]&lt;/span&gt;,
  &lt;span class="o"&gt;}&lt;/span&gt;,
  &lt;span class="o"&gt;{&lt;/span&gt;
    elementType: &lt;span class="s1"&gt;'labels.text.fill'&lt;/span&gt;,
    stylers: &lt;span class="o"&gt;[{&lt;/span&gt; color: &lt;span class="s1"&gt;'#757575'&lt;/span&gt; &lt;span class="o"&gt;}]&lt;/span&gt;,
  &lt;span class="o"&gt;}&lt;/span&gt;,
&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&amp;lt;MapView
  &lt;span class="nv"&gt;customMapStyle&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;customMapStyle&lt;span class="o"&gt;}&lt;/span&gt;
  ...
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Map integration in React Native can be tricky — especially when balancing permission flow and native dependencies — but once set up properly, it unlocks powerful location-based features for your users.&lt;/p&gt;

&lt;p&gt;The key takeaways:&lt;br&gt;
✅ Always request permissions before rendering the map&lt;/p&gt;

&lt;p&gt;✅ Handle &lt;code&gt;showsUserLocation&lt;/code&gt; carefully on Android&lt;/p&gt;

&lt;p&gt;✅ Use dynamic regions for better UX&lt;/p&gt;

&lt;p&gt;✅ Customize your map style to match your app&lt;/p&gt;




&lt;h3&gt;
  
  
  Coming Up Next
&lt;/h3&gt;

&lt;p&gt;In my next post, I’ll cover “Building a Location Picker with React Native Maps” — where users can drag the map to set an address or store location.&lt;/p&gt;




&lt;p&gt;✍️ Written by &lt;a href="https://www.linkedin.com/in/dainyjose" rel="noopener noreferrer"&gt;&lt;strong&gt;Dainy Jose&lt;/strong&gt;&lt;/a&gt; — React Native Mobile Application Developer with 3+ years of experience building cross-platform mobile apps using &lt;strong&gt;React Native (Expo, TypeScript, Redux)&lt;/strong&gt;. &lt;br&gt;
Currently expanding backend knowledge through the &lt;strong&gt;MERN Stack (MongoDB, Express.js, React.js, Node.js)&lt;/strong&gt; to create more efficient, full-stack mobile experiences.&lt;/p&gt;

&lt;p&gt;💼 &lt;strong&gt;Tech Stack:&lt;/strong&gt; React Native · TypeScript · Redux · Expo · Firebase · Node.js · Express.js · MongoDB · REST API · JWT · Jest · Google Maps · Razorpay · PayU · Agile · SDLC · Git · Bitbucket · Jira &lt;/p&gt;

&lt;p&gt;📬 &lt;strong&gt;Connect with me&lt;/strong&gt;:&lt;br&gt;
🌐 &lt;a href="https://dainyjose.github.io/my-portfolio/" rel="noopener noreferrer"&gt;Portfolio&lt;/a&gt;&lt;br&gt;
🔗 &lt;a href="https://www.linkedin.com/in/dainyjose" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;br&gt;
💻 &lt;a href="https://github.com/dainyjose" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>map</category>
      <category>android</category>
      <category>ios</category>
    </item>
    <item>
      <title>Step-by-Step Guide to Upgrading Your React Native Expo Project</title>
      <dc:creator>Dainy Jose</dc:creator>
      <pubDate>Sun, 02 Nov 2025 16:31:06 +0000</pubDate>
      <link>https://forem.com/dainyjose/step-by-step-guide-to-upgrading-your-react-native-expo-project-1fio</link>
      <guid>https://forem.com/dainyjose/step-by-step-guide-to-upgrading-your-react-native-expo-project-1fio</guid>
      <description>&lt;p&gt;Upgrading a React Native Expo project can seem intimidating — especially when juggling native modules, custom configurations, and environment files. But with the right plan, it can be smooth and predictable.&lt;/p&gt;

&lt;p&gt;In this post, I’ll walk you through a practical guide for upgrading an Expo project (bare or managed workflow) while keeping your setup stable and maintainable.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Upgrade Regularly?
&lt;/h2&gt;

&lt;p&gt;Regular upgrades ensure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Access to the latest React Native and Expo features&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Improved performance and security&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Compatibility with new OS releases&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Easier future maintenance&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Neglecting upgrades can cause dependency conflicts, native crashes, or build failures during future updates — which are far harder to resolve later.&lt;/p&gt;




&lt;h2&gt;
  
  
  Before You Begin
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Check the Current SDK Version
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;expo &lt;span class="nt"&gt;--version&lt;/span&gt;
expo config &lt;span class="nt"&gt;--json&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;sdkVersion
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Review the Upgrade Guides
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.expo.dev/versions/latest/" rel="noopener noreferrer"&gt;Expo SDK Release Notes&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://react-native-community.github.io/upgrade-helper/" rel="noopener noreferrer"&gt;React Native Upgrade Helper&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Create a Backup
&lt;/h3&gt;

&lt;p&gt;Always create a branch for the upgrade:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; upgrade/sdk-52
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Update Environment Files
&lt;/h3&gt;

&lt;p&gt;Ensure &lt;code&gt;.env.development&lt;/code&gt; and &lt;code&gt;.env.production&lt;/code&gt; are consistent.&lt;br&gt;
Tip: Use a library like &lt;code&gt;react-native-dotenv&lt;/code&gt; for environment management.&lt;/p&gt;


&lt;h2&gt;
  
  
  Step 1: Upgrade Expo SDK
&lt;/h2&gt;

&lt;p&gt;Run the official upgrade command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx expo upgrade
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This automatically updates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Expo SDK version&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Related dependencies (&lt;code&gt;expo-*&lt;/code&gt; packages)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;iOS and Android native projects (if using bare workflow)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’re in a bare workflow, run &lt;code&gt;pod install&lt;/code&gt; inside the &lt;code&gt;ios&lt;/code&gt; directory after upgrading.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2: Update React Native and Dependencies
&lt;/h2&gt;

&lt;p&gt;Check your current versions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm list react react-native
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, align them with the new Expo SDK version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;react@latest react-native@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you’re using TypeScript, also update:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;typescript @types/react @types/react-native &lt;span class="nt"&gt;--save-dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 3: Clear Cache and Reset Metro Bundler
&lt;/h2&gt;

&lt;p&gt;After upgrading, clear the caches to avoid stale modules:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;watchman watch-del-all
&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; node_modules
&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; &lt;span class="nv"&gt;$TMPDIR&lt;/span&gt;/metro-&lt;span class="k"&gt;*&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 4: Verify Native Modules
&lt;/h2&gt;

&lt;p&gt;If you use libraries like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;react-native-vision-camera&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;react-native-share&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;react-native-blob-util&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;notifee/react-native&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ensure they’re compatible with the new SDK:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx expo doctor
npx pod-install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For bare workflow users, verify your native modules in &lt;code&gt;MainApplication.kt&lt;/code&gt; / &lt;code&gt;AppDelegate.mm&lt;/code&gt; after upgrading.&lt;/p&gt;




&lt;p&gt;Step 5: Test Build on Both Platforms&lt;/p&gt;

&lt;p&gt;Run the project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx expo run:android
npx expo run:ios
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you face issues, open the build logs and look for deprecated properties or mismatched dependencies.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 6: Validate App Behavior
&lt;/h2&gt;

&lt;p&gt;Check these:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Splash screen hides correctly&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Environment variables load properly&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;File sharing, notifications, and camera modules still work&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Production build signs and runs as expected&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can also test locally with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx expo start &lt;span class="nt"&gt;--clear&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 7: Commit and Tag the Upgrade
&lt;/h2&gt;

&lt;p&gt;Once stable, commit your changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"chore: upgrade to Expo SDK 52 + RN 0.77"&lt;/span&gt;
git tag v1.2.0-upgrade
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Pro Tips
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use Dependabot or Renovate&lt;/strong&gt;: Automate version tracking.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Keep a Changelog&lt;/strong&gt;: Helps you and your team track upgrade impacts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Test on Real Devices&lt;/strong&gt;: Emulators don’t always reflect real-world issues.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Avoid Skipping SDKs&lt;/strong&gt;: Skipping major versions makes future upgrades painful.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;Upgrading your Expo project doesn’t have to break your flow.&lt;br&gt;
With the right steps — backups, incremental updates, and consistent testing — you can keep your project &lt;strong&gt;future-proof, stable, and developer-friendly&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you found this helpful, leave a ❤️ or share how you manage upgrades in your own Expo workflow!&lt;/p&gt;




&lt;p&gt;✍️ Written by &lt;a href="https://www.linkedin.com/in/dainyjose" rel="noopener noreferrer"&gt;&lt;strong&gt;Dainy Jose&lt;/strong&gt;&lt;/a&gt; — React Native Mobile Application Developer with 3+ years of experience building cross-platform mobile apps using &lt;strong&gt;React Native (Expo, TypeScript, Redux)&lt;/strong&gt;. &lt;br&gt;
Currently expanding backend knowledge through the &lt;strong&gt;MERN Stack (MongoDB, Express.js, React.js, Node.js)&lt;/strong&gt; to create more efficient, full-stack mobile experiences.&lt;/p&gt;

&lt;p&gt;💼 &lt;strong&gt;Tech Stack:&lt;/strong&gt; React Native · TypeScript · Redux · Expo · Firebase · Node.js · Express.js · MongoDB · REST API · JWT · Jest · Google Maps · Razorpay · PayU · Agile · SDLC · Git · Bitbucket · Jira &lt;/p&gt;

&lt;p&gt;📬 &lt;strong&gt;Connect with me&lt;/strong&gt;:&lt;br&gt;
🌐 &lt;a href="https://dainyjose.github.io/my-portfolio/" rel="noopener noreferrer"&gt;Portfolio&lt;/a&gt;&lt;br&gt;
🔗 &lt;a href="https://www.linkedin.com/in/dainyjose" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;br&gt;
💻 &lt;a href="https://github.com/dainyjose" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>mobile</category>
      <category>development</category>
      <category>typescript</category>
    </item>
    <item>
      <title>How I Built My Developer Portfolio with Vite, React, and Bun — Fast, Modern &amp; Fully Customizable</title>
      <dc:creator>Dainy Jose</dc:creator>
      <pubDate>Sun, 02 Nov 2025 14:52:41 +0000</pubDate>
      <link>https://forem.com/dainyjose/how-i-built-my-developer-portfolio-with-vite-react-and-bun-fast-modern-fully-customizable-410b</link>
      <guid>https://forem.com/dainyjose/how-i-built-my-developer-portfolio-with-vite-react-and-bun-fast-modern-fully-customizable-410b</guid>
      <description>&lt;p&gt;&lt;em&gt;A lightweight, modular portfolio built with Vite + React + TypeScript + Bun, designed to showcase projects, blogs, and achievements — built from scratch with simplicity and speed in mind.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I Built It
&lt;/h2&gt;

&lt;p&gt;As developers, our portfolios are often the first impression we make — so I wanted mine to be &lt;strong&gt;clean, fast, and easy to maintain&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I experimented with several static site tools before finding the perfect trio: &lt;strong&gt;Vite, React&lt;/strong&gt;, and &lt;strong&gt;Bun&lt;/strong&gt;.&lt;br&gt;
This stack offered everything I wanted — modern development, instant reloads, and a minimal setup that just works.&lt;/p&gt;

&lt;p&gt;👉 Live Demo: &lt;a href="https://dainyjose.github.io/my-portfolio/" rel="noopener noreferrer"&gt;https://dainyjose.github.io/my-portfolio/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉 Source Code: &lt;a href="https://github.com/dainyjose/my-portfolio" rel="noopener noreferrer"&gt;https://github.com/dainyjose/my-portfolio&lt;/a&gt;&lt;/p&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Vite&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Lightning-fast build tool with instant HMR&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;React + TypeScript&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Component-based architecture with type safety&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Bun&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Fast JavaScript runtime &amp;amp; package manager&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CSS Modules&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Clean and scoped component styling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GitHub Pages&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Simple and free static site hosting&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;


&lt;h2&gt;
  
  
  Setting Up the Project
&lt;/h2&gt;

&lt;p&gt;Vite and Bun make setting up a React + TypeScript project almost instant.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create a new Vite + React + TypeScript project&lt;/span&gt;
bun create vite my-portfolio &lt;span class="nt"&gt;--template&lt;/span&gt; react-ts

&lt;span class="nb"&gt;cd &lt;/span&gt;my-portfolio

&lt;span class="c"&gt;# Install dependencies (super fast!)&lt;/span&gt;
bun &lt;span class="nb"&gt;install&lt;/span&gt;

&lt;span class="c"&gt;# Start the dev server&lt;/span&gt;
bun run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Within seconds, the project is live with hot reload and TypeScript support.&lt;/p&gt;




&lt;h2&gt;
  
  
  Project Structure
&lt;/h2&gt;

&lt;p&gt;Here’s how I organized my portfolio for clarity and scalability:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;my-portfolio/
 ┣ src/
 ┃ ┣ components/
 ┃ ┣ pages/
 ┃ ┣ data/
 ┃ ┣ assets/
 ┃ ┗ App.tsx
 ┣ public/
 ┣ index.html
 ┣ vite.config.ts
 ┗ bun.lockb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Highlights:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;components/&lt;/code&gt; → Reusable UI elements (Header, Footer, ProjectCard, etc.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;pages/&lt;/code&gt; → Sections like Home, About, Projects, and Contact&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;data/&lt;/code&gt; → Static project data and links&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;assets/&lt;/code&gt; → Images and icons&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Designing the UI
&lt;/h2&gt;

&lt;p&gt;I went for a &lt;strong&gt;simple, professional design&lt;/strong&gt; — no UI frameworks or heavy styling libraries, just clean &lt;strong&gt;CSS&lt;/strong&gt; Modules for scoped styles.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;// src/components/Header.tsx
import styles from &lt;span class="s2"&gt;"./header.css"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nb"&gt;export &lt;/span&gt;const Header &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;
  &amp;lt;header &lt;span class="nv"&gt;className&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;styles.header&lt;span class="o"&gt;}&amp;gt;&lt;/span&gt;
    &amp;lt;h1 &lt;span class="nv"&gt;className&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;styles.title&lt;span class="o"&gt;}&amp;gt;&lt;/span&gt;Dainy Jose&amp;lt;/h1&amp;gt;
    &amp;lt;nav &lt;span class="nv"&gt;className&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;styles.nav&lt;span class="o"&gt;}&amp;gt;&lt;/span&gt;
      &amp;lt;a &lt;span class="nv"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"#projects"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;Projects&amp;lt;/a&amp;gt;
      &amp;lt;a &lt;span class="nv"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"#contact"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;Contact&amp;lt;/a&amp;gt;
    &amp;lt;/nav&amp;gt;
  &amp;lt;/header&amp;gt;
&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/&lt;span class="k"&gt;*&lt;/span&gt; src/components/header.css &lt;span class="k"&gt;*&lt;/span&gt;/
.header &lt;span class="o"&gt;{&lt;/span&gt;
  display: flex&lt;span class="p"&gt;;&lt;/span&gt;
  justify-content: space-between&lt;span class="p"&gt;;&lt;/span&gt;
  align-items: center&lt;span class="p"&gt;;&lt;/span&gt;
  padding: 1rem 2rem&lt;span class="p"&gt;;&lt;/span&gt;
  background-color: &lt;span class="c"&gt;#ffffff;&lt;/span&gt;
  border-bottom: 1px solid &lt;span class="c"&gt;#eaeaea;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

.title &lt;span class="o"&gt;{&lt;/span&gt;
  font-size: 1.6rem&lt;span class="p"&gt;;&lt;/span&gt;
  font-weight: 600&lt;span class="p"&gt;;&lt;/span&gt;
  color: &lt;span class="c"&gt;#222;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

.nav a &lt;span class="o"&gt;{&lt;/span&gt;
  margin-left: 1rem&lt;span class="p"&gt;;&lt;/span&gt;
  text-decoration: none&lt;span class="p"&gt;;&lt;/span&gt;
  color: &lt;span class="c"&gt;#007bff;&lt;/span&gt;
  transition: color 0.2s&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

.nav a:hover &lt;span class="o"&gt;{&lt;/span&gt;
  color: &lt;span class="c"&gt;#0056b3;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives full control over the look while keeping the CSS lightweight and maintainable.&lt;/p&gt;




&lt;h2&gt;
  
  
  Adding Projects &amp;amp; Blogs
&lt;/h2&gt;

&lt;p&gt;To make it easy to update, I store all portfolio items in a single &lt;code&gt;data/projects.ts&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;// src/data/projects.ts
&lt;span class="nb"&gt;export &lt;/span&gt;const projects &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;
  &lt;span class="o"&gt;{&lt;/span&gt;
    name: &lt;span class="s2"&gt;"My Resume App"&lt;/span&gt;,
    description: &lt;span class="s2"&gt;"Created using React + Vite."&lt;/span&gt;,
    &lt;span class="nb"&gt;link&lt;/span&gt;: &lt;span class="s2"&gt;"https://dainyjose.github.io/my-resume/"&lt;/span&gt;,
  &lt;span class="o"&gt;}&lt;/span&gt;,
&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And render them dynamically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;// src/components/Projects.tsx
import &lt;span class="o"&gt;{&lt;/span&gt; projects &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s2"&gt;"../data/projects"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nb"&gt;export &lt;/span&gt;const Projects &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;
  &amp;lt;section &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"projects"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &amp;lt;h2&amp;gt;Projects&amp;lt;/h2&amp;gt;
    &lt;span class="o"&gt;{&lt;/span&gt;projects.map&lt;span class="o"&gt;((&lt;/span&gt;p&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;
      &amp;lt;a &lt;span class="nv"&gt;key&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;p.name&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="nv"&gt;href&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;p.link&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="nv"&gt;target&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"_blank"&lt;/span&gt; &lt;span class="nv"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"noopener noreferrer"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &amp;lt;h3&amp;gt;&lt;span class="o"&gt;{&lt;/span&gt;p.name&lt;span class="o"&gt;}&lt;/span&gt;&amp;lt;/h3&amp;gt;
        &amp;lt;p&amp;gt;&lt;span class="o"&gt;{&lt;/span&gt;p.description&lt;span class="o"&gt;}&lt;/span&gt;&amp;lt;/p&amp;gt;
      &amp;lt;/a&amp;gt;
    &lt;span class="o"&gt;))}&lt;/span&gt;
  &amp;lt;/section&amp;gt;
&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes adding new projects as easy as editing one file.&lt;/p&gt;




&lt;h2&gt;
  
  
  Optimizing for Performance
&lt;/h2&gt;

&lt;p&gt;To keep the site fast:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Compressed images manually before adding to &lt;code&gt;assets/&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Leveraged Vite’s built-in minification and bundling&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bun handled builds incredibly fast&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every rebuild or deploy took only a few seconds.&lt;/p&gt;




&lt;h2&gt;
  
  
  Deployment
&lt;/h2&gt;

&lt;p&gt;I hosted the portfolio on &lt;strong&gt;GitHub Pages&lt;/strong&gt; using a simple build + deploy command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="s2"&gt;"scripts"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"dev"&lt;/span&gt;: &lt;span class="s2"&gt;"vite"&lt;/span&gt;,
  &lt;span class="s2"&gt;"build"&lt;/span&gt;: &lt;span class="s2"&gt;"vite build"&lt;/span&gt;,
  &lt;span class="s2"&gt;"preview"&lt;/span&gt;: &lt;span class="s2"&gt;"vite preview"&lt;/span&gt;,
  &lt;span class="s2"&gt;"deploy"&lt;/span&gt;: &lt;span class="s2"&gt;"gh-pages -d dist"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then deployed with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bun run build
bun run deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In just a few seconds, the site was live:&lt;br&gt;
➡️ &lt;a href="https://dainyjose.github.io/my-portfolio" rel="noopener noreferrer"&gt;https://dainyjose.github.io/my-portfolio&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Bun + Vite make development effortless&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The build and dev speed is unbeatable.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;TypeScript ensures long-term scalability&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Strong typing helps maintain clean code.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;CSS Modules keep styling simple and scoped&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Easy to maintain and modify as the portfolio grows.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;GitHub Pages = quick deployment&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Perfect for personal projects and static sites.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  What’s Next
&lt;/h2&gt;

&lt;p&gt;I plan to enhance the portfolio with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Dark mode toggle&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GitHub API integration to auto-fetch repositories&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dev.to API integration for displaying latest blog posts&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;This project reminded me that &lt;strong&gt;simplicity is powerful&lt;/strong&gt;.&lt;br&gt;
You don’t need complex tools or heavy UI frameworks to create something elegant and efficient.&lt;/p&gt;

&lt;p&gt;If you’re building your portfolio, I highly recommend giving &lt;strong&gt;Vite + React + Bun&lt;/strong&gt; a try — you’ll be surprised by how smooth the workflow is.&lt;/p&gt;

&lt;p&gt;🔗 Repo: &lt;a href="https://github.com/dainyjose/my-portfolio" rel="noopener noreferrer"&gt;https://github.com/dainyjose/my-portfolio&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🌐 Live: &lt;a href="https://dainyjose.github.io/my-portfolio/" rel="noopener noreferrer"&gt;https://dainyjose.github.io/my-portfolio/&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;✍️ Written by &lt;a href="https://www.linkedin.com/in/dainyjose" rel="noopener noreferrer"&gt;&lt;strong&gt;Dainy Jose&lt;/strong&gt;&lt;/a&gt; — React Native Mobile Application Developer with 3+ years of experience building cross-platform mobile apps using &lt;strong&gt;React Native (Expo, TypeScript, Redux)&lt;/strong&gt;. &lt;br&gt;
Currently expanding backend knowledge through the &lt;strong&gt;MERN Stack (MongoDB, Express.js, React.js, Node.js)&lt;/strong&gt; to create more efficient, full-stack mobile experiences.&lt;/p&gt;

&lt;p&gt;💼 &lt;strong&gt;Tech Stack:&lt;/strong&gt; React Native · TypeScript · Redux · Expo · Firebase · Node.js · Express.js · MongoDB · REST API · JWT · Jest · Google Maps · Razorpay · PayU · Agile · SDLC · Git · Bitbucket · Jira &lt;/p&gt;

&lt;p&gt;📬 &lt;strong&gt;Connect with me&lt;/strong&gt;:&lt;br&gt;
🌐 &lt;a href="https://dainyjose.github.io/my-portfolio/" rel="noopener noreferrer"&gt;Portfolio&lt;/a&gt;&lt;br&gt;
🔗 &lt;a href="https://www.linkedin.com/in/dainyjose" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;br&gt;
💻 &lt;a href="https://github.com/dainyjose" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>vite</category>
      <category>portfolio</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Advanced Push &amp; Local Notifications in React Native with Firebase and Notifee (Part 2)</title>
      <dc:creator>Dainy Jose</dc:creator>
      <pubDate>Tue, 28 Oct 2025 15:56:27 +0000</pubDate>
      <link>https://forem.com/dainyjose/advanced-push-local-notifications-in-react-native-with-firebase-and-notifee-part-2-2mn6</link>
      <guid>https://forem.com/dainyjose/advanced-push-local-notifications-in-react-native-with-firebase-and-notifee-part-2-2mn6</guid>
      <description>&lt;p&gt;In the &lt;a href="https://dev.to/dainyjose/implementing-push-notifications-in-react-native-using-firebase-and-notifee-ahl"&gt;first part&lt;/a&gt; of this series, we built a complete &lt;strong&gt;Firebase Cloud Messaging (FCM)&lt;/strong&gt; setup for &lt;strong&gt;React Native&lt;/strong&gt; using &lt;strong&gt;Firebase&lt;/strong&gt; and &lt;strong&gt;Notifee&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now, in &lt;strong&gt;Part 2&lt;/strong&gt;, we’ll go deeper and explore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📱 Local notifications
&lt;/li&gt;
&lt;li&gt;✨ Custom notification styles
&lt;/li&gt;
&lt;li&gt;⏰ Triggers and scheduling
&lt;/li&gt;
&lt;li&gt;⚡ Action buttons and backend integration
&lt;/li&gt;
&lt;li&gt;🎧 Media and chat-style notifications
&lt;/li&gt;
&lt;li&gt;📊 Event tracking for every app state (Foreground, Background, Killed)
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This part focuses on building a &lt;strong&gt;robust notification system&lt;/strong&gt; that behaves consistently across app states — with fixes to ensure reliable delivery and accurate navigation.&lt;/p&gt;




&lt;h2&gt;
  
  
  📱 1. Local Notifications with Notifee
&lt;/h2&gt;

&lt;p&gt;Local notifications are shown &lt;strong&gt;without FCM&lt;/strong&gt;, usually triggered by in-app events — such as reminders or task completions.&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;notifee&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AndroidImportance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;TriggerType&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;@notifee/react-native&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Simple local notification&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;showLocalNotification&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;notifee&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;channelId&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;notifee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createChannel&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;local&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Local Notifications&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;importance&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AndroidImportance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;HIGH&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;notifee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;displayNotification&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="s2"&gt;'NotifyMeApp Reminder',&lt;/span&gt;&lt;span class="dl"&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="s1"&gt;Your scheduled task is ready!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;android&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;channelId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;smallIcon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ic_launcher&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can call &lt;code&gt;showLocalNotification()&lt;/code&gt; anywhere — even as a response to user actions or events.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⏰ 2. Notification Triggers
&lt;/h2&gt;

&lt;p&gt;Notifee allows &lt;strong&gt;scheduled&lt;/strong&gt; or &lt;strong&gt;event-based&lt;/strong&gt; notifications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: Trigger after 10 seconds&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;trigger&lt;/span&gt; &lt;span class="o"&gt;=&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="nx"&gt;TriggerType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;TIMESTAMP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// 10 seconds later&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;notifee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createTriggerNotification&lt;/span&gt;&lt;span class="p"&gt;(&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="s1"&gt;NotifyMeApp&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="s1"&gt;⏰ Scheduled notification fired!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;android&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;channelId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;local&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;trigger&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;Example: Repeat daily reminder&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;trigger&lt;/span&gt; &lt;span class="o"&gt;=&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="nx"&gt;TriggerType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;INTERVAL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;interval&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// every 24 hours&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;notifee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createTriggerNotification&lt;/span&gt;&lt;span class="p"&gt;(&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="s1"&gt;Daily Reminder&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="s1"&gt;It’s time to check new updates!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;android&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;channelId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;local&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;trigger&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🧱 3. Customizing Notifications
&lt;/h2&gt;

&lt;p&gt;You can completely customize your notification look using Notifee’s Android styles.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Big Picture Style (with Image)&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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;notifee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;displayNotification&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="s1"&gt;New Offer Available 🎉&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="s1"&gt;Get 20% off on your next rental!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;android&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;channelId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;promo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&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="nx"&gt;notifee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AndroidStyle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;BIGPICTURE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;picture&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://example.com/offer-banner.jpg&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Messaging Style (for Chat)&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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;notifee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;displayNotification&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="s1"&gt;John Doe&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="s1"&gt;Hey! Are you available for the shoot tomorrow?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;android&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;channelId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;chat&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&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="nx"&gt;notifee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AndroidStyle&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="na"&gt;person&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John Doe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;messages&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="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hey! Are you available for the shoot tomorrow?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&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="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;
  
  
  ⚙️ 4. Notification Actions (with Backend Support)
&lt;/h2&gt;

&lt;p&gt;Add buttons directly to your notifications to trigger specific actions.&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="c"&gt;&amp;lt;!--&lt;/span&gt; &lt;span class="nx"&gt;AndroidManifest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;xml&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;activity&lt;/span&gt; &lt;span class="nx"&gt;android&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.MainActivity&lt;/span&gt;&lt;span class="dl"&gt;"&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;intent&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;filter&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;action&lt;/span&gt; &lt;span class="nx"&gt;android&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;OPEN_ACTIVITY_1&lt;/span&gt;&lt;span class="dl"&gt;"&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;category&lt;/span&gt; &lt;span class="nx"&gt;android&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;android.intent.category.DEFAULT&lt;/span&gt;&lt;span class="dl"&gt;"&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;/intent-filter&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;/activity&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then in your notification payload (from backend):&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;const&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&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="na"&gt;notification&lt;/span&gt;&lt;span class="p"&gt;:&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="s1"&gt;NotifyMeApp&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="s1"&gt;New message received&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="na"&gt;android&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;channelId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;chat&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;actions&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="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="s1"&gt;Reply&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;pressAction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;OPEN_ACTIVITY_1&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="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;In your app:&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;notifee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onForegroundEvent&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;detail&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;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;notifee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;EventType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ACTION_PRESS&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;detail&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pressAction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;OPEN_ACTIVITY_1&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="s1"&gt;User tapped Reply button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// Backend can be notified here (e.g., mark as read or open chat)&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;
  
  
  🧠 5. Notification Events Across App States
&lt;/h2&gt;

&lt;p&gt;Recent improvements have made notifications behave &lt;strong&gt;consistently&lt;/strong&gt; across all app states.&lt;br&gt;
Here’s how you can handle each transition cleanly 👇&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Received In&lt;/th&gt;
&lt;th&gt;Opened From&lt;/th&gt;
&lt;th&gt;Expected Behavior&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Foreground&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Foreground&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Show custom in-app popup or Notifee local notification&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Foreground&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Background&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Navigate to target screen after resume&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Foreground&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Killed&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Use &lt;code&gt;getInitialNotification()&lt;/code&gt; to handle navigation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Background&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Foreground&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Auto-navigate to notification target&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Background&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Background&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Open directly to target screen&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Background&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Killed&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Retrieve data from FCM launch event&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Killed&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Foreground&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Fetch from last FCM message using &lt;code&gt;onNotificationOpenedApp&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Killed&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Background&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Same as above — delayed navigation allowed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Killed&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Killed&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Delivered silently; handle upon next app launch&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Implementation Example&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;messaging&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-native-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="nx"&gt;notifee&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;@notifee/react-native&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;navigationRef&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;./NavigationService&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Foreground messages&lt;/span&gt;
&lt;span class="nf"&gt;messaging&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="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;remoteMessage&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;await&lt;/span&gt; &lt;span class="nx"&gt;notifee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;displayNotification&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;remoteMessage&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;remoteMessage&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="na"&gt;android&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;channelId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;default&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="c1"&gt;// When app is opened from background&lt;/span&gt;
&lt;span class="nf"&gt;messaging&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;onNotificationOpenedApp&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;remoteMessage&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;screen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;remoteMessage&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="nx"&gt;targetScreen&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;screen&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;navigationRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;navigate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// When app is launched from a killed state&lt;/span&gt;
&lt;span class="nf"&gt;messaging&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getInitialNotification&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;remoteMessage&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;remoteMessage&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;screen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;remoteMessage&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="nx"&gt;targetScreen&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;screen&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;navigationRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;navigate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;screen&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;h2&gt;
  
  
  🎧 6. Media &amp;amp; Chat Notifications
&lt;/h2&gt;

&lt;p&gt;To include images, videos, or chat previews inside notifications:&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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;notifee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;displayNotification&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="s1"&gt;🎬 Video Upload Complete!&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="s1"&gt;Your project is now ready to share.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;android&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;channelId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;media&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&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="nx"&gt;notifee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AndroidStyle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;BIGPICTURE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;picture&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://example.com/video-thumbnail.jpg&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For chat-like experience:&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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;notifee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;displayNotification&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="s1"&gt;Anna&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="s1"&gt;Hey! New project details are ready!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;android&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;channelId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;chat&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&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="nx"&gt;notifee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AndroidStyle&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="na"&gt;person&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Anna&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;messages&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="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hey! New project details are ready!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&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="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Let’s discuss soon.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&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="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;
  
  
  ✅ Key Fixes and Improvements
&lt;/h2&gt;

&lt;p&gt;In the latest implementation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Notifications tapped from a &lt;strong&gt;killed&lt;/strong&gt; state now navigate correctly.&lt;/li&gt;
&lt;li&gt;Foreground notifications no longer duplicate when both FCM and Notifee handlers are active.&lt;/li&gt;
&lt;li&gt;Deep links from &lt;strong&gt;background&lt;/strong&gt; notifications navigate smoothly on resume.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Resolved by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using &lt;code&gt;getInitialNotification()&lt;/code&gt; for cold starts&lt;/li&gt;
&lt;li&gt;Ensuring single &lt;strong&gt;Notifee channel creation&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Separating &lt;strong&gt;local + FCM handlers&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Maintaining event order for consistent navigation&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🎯 Wrapping Up
&lt;/h2&gt;

&lt;p&gt;In this advanced guide, we covered:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Local &amp;amp; scheduled notifications&lt;/li&gt;
&lt;li&gt;Trigger-based alerts&lt;/li&gt;
&lt;li&gt;Media and chat-style notifications&lt;/li&gt;
&lt;li&gt;Custom action buttons integrated with backend&lt;/li&gt;
&lt;li&gt;Complete event handling across all app states&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Together with &lt;strong&gt;Part 1&lt;/strong&gt;, you now have a &lt;strong&gt;production-ready notification system&lt;/strong&gt; for any React Native app.&lt;/p&gt;




&lt;p&gt;✍️ Written by &lt;a href="https://www.linkedin.com/in/dainyjose" rel="noopener noreferrer"&gt;&lt;strong&gt;Dainy Jose&lt;/strong&gt;&lt;/a&gt; — React Native Mobile Application Developer with 3+ years of experience building cross-platform mobile apps using &lt;strong&gt;React Native (Expo, TypeScript, Redux)&lt;/strong&gt;. &lt;br&gt;
Currently expanding backend knowledge through the &lt;strong&gt;MERN Stack (MongoDB, Express.js, React.js, Node.js)&lt;/strong&gt; to create more efficient, full-stack mobile experiences.&lt;/p&gt;

&lt;p&gt;💼 &lt;strong&gt;Tech Stack:&lt;/strong&gt; React Native · TypeScript · Redux · Expo · Firebase · Node.js · Express.js · MongoDB · REST API · JWT · Jest · Google Maps · Razorpay · PayU · Agile · SDLC · Git · Bitbucket · Jira &lt;/p&gt;

&lt;p&gt;📬 &lt;strong&gt;Connect with me&lt;/strong&gt;:&lt;br&gt;
🌐 &lt;a href="https://dainyjose.github.io/my-portfolio/" rel="noopener noreferrer"&gt;Portfolio&lt;/a&gt;&lt;br&gt;
🔗 &lt;a href="https://www.linkedin.com/in/dainyjose" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;br&gt;
💻 &lt;a href="https://github.com/dainyjose" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>firebase</category>
      <category>mobile</category>
      <category>notifications</category>
    </item>
    <item>
      <title>Implementing Push Notifications in React Native Using Firebase and Notifee</title>
      <dc:creator>Dainy Jose</dc:creator>
      <pubDate>Fri, 17 Oct 2025 05:24:55 +0000</pubDate>
      <link>https://forem.com/dainyjose/implementing-push-notifications-in-react-native-using-firebase-and-notifee-ahl</link>
      <guid>https://forem.com/dainyjose/implementing-push-notifications-in-react-native-using-firebase-and-notifee-ahl</guid>
      <description>&lt;p&gt;Push notifications are one of the most effective ways to re-engage users and deliver timely updates.&lt;br&gt;
In this article, we’ll walk through &lt;strong&gt;implementing FCM (Firebase Cloud Messaging) push notifications&lt;/strong&gt; in a &lt;strong&gt;React Native app&lt;/strong&gt; using &lt;strong&gt;Firebase&lt;/strong&gt; and &lt;strong&gt;Notifee&lt;/strong&gt;, covering both mobile-side setup and backend integration.&lt;/p&gt;


&lt;h2&gt;
  
  
  🧩 Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before we dive in, make sure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A React Native project (Expo bare workflow or React Native CLI)&lt;/li&gt;
&lt;li&gt;Node.js and npm/yarn installed&lt;/li&gt;
&lt;li&gt;A Firebase account&lt;/li&gt;
&lt;li&gt;Basic understanding of backend APIs&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;
  
  
  🪄 Step 1: Firebase Setup
&lt;/h3&gt;
&lt;h4&gt;
  
  
  1️⃣ Create a Firebase Project
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Go to Firebase Console&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Add Project&lt;/strong&gt; → enter a name (e.g., &lt;code&gt;NotifyMeApp&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Disable Google Analytics (optional) → click &lt;strong&gt;Create Project&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;
  
  
  2️⃣ Add Android App to Firebase
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;In your Firebase project → click &lt;strong&gt;Add App → Android&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Enter your package name (from &lt;code&gt;android/app/build.gradle&lt;/code&gt;, e.g. &lt;code&gt;com.notifyme.app&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Download the &lt;code&gt;google-services.json&lt;/code&gt; file&lt;/li&gt;
&lt;li&gt;Move it to your project:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   android/app/google-services.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;5.Add Firebase plugin in &lt;code&gt;android/build.gradle&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;buildscript &lt;span class="o"&gt;{&lt;/span&gt;
  dependencies &lt;span class="o"&gt;{&lt;/span&gt;
    classpath &lt;span class="s1"&gt;'com.google.gms:google-services:4.4.2'&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;6.Then, apply the plugin in &lt;code&gt;android/app/build.gradle&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apply plugin: &lt;span class="s1"&gt;'com.google.gms.google-services'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3️⃣ Add iOS App (if applicable)
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Add your iOS bundle ID (from Xcode → Targets → General → Bundle Identifier)&lt;/li&gt;
&lt;li&gt;Download &lt;code&gt;GoogleService-Info.plist&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Add it to your iOS project in Xcode&lt;/li&gt;
&lt;li&gt;Run:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;ios &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; pod &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd&lt;/span&gt; ..
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  📱 Step 2: React Native Mobile Setup
&lt;/h3&gt;

&lt;p&gt;We’ll use two key libraries:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;@react-native-firebase/messaging&lt;/code&gt; – for handling FCM&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@notifee/react-native&lt;/code&gt; – for advanced notification control&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  1️⃣ Install Dependencies
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add @react-native-firebase/app @react-native-firebase/messaging @notifee/react-native
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @react-native-firebase/app @react-native-firebase/messaging @notifee/react-native
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For iOS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;ios &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; pod &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd&lt;/span&gt; ..
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2️⃣ Request Notification Permission
&lt;/h4&gt;

&lt;p&gt;Create a file &lt;code&gt;NotificationService.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;import messaging from &lt;span class="s1"&gt;'@react-native-firebase/messaging'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import notifee, &lt;span class="o"&gt;{&lt;/span&gt; AndroidImportance &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s1"&gt;'@notifee/react-native'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import &lt;span class="o"&gt;{&lt;/span&gt; Platform &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s1"&gt;'react-native'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

class NotificationService &lt;span class="o"&gt;{&lt;/span&gt;
  static async requestPermission&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    const authStatus &lt;span class="o"&gt;=&lt;/span&gt; await messaging&lt;span class="o"&gt;()&lt;/span&gt;.requestPermission&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    const enabled &lt;span class="o"&gt;=&lt;/span&gt;
      authStatus &lt;span class="o"&gt;===&lt;/span&gt; messaging.AuthorizationStatus.AUTHORIZED &lt;span class="o"&gt;||&lt;/span&gt;
      authStatus &lt;span class="o"&gt;===&lt;/span&gt; messaging.AuthorizationStatus.PROVISIONAL&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;enabled&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      console.log&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Authorization status:'&lt;/span&gt;, authStatus&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      this.getFcmToken&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  static async getFcmToken&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    const token &lt;span class="o"&gt;=&lt;/span&gt; await messaging&lt;span class="o"&gt;()&lt;/span&gt;.getToken&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    console.log&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'FCM Token:'&lt;/span&gt;, token&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    // Send this token to your backend to store it
  &lt;span class="o"&gt;}&lt;/span&gt;

  static async onMessageListener&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    messaging&lt;span class="o"&gt;()&lt;/span&gt;.onMessage&lt;span class="o"&gt;(&lt;/span&gt;async &lt;span class="o"&gt;(&lt;/span&gt;remoteMessage&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      await notifee.displayNotification&lt;span class="o"&gt;({&lt;/span&gt;
        title: remoteMessage.notification?.title,
        body: remoteMessage.notification?.body,
        android: &lt;span class="o"&gt;{&lt;/span&gt;
          channelId: &lt;span class="s1"&gt;'default'&lt;/span&gt;,
          importance: AndroidImportance.HIGH,
        &lt;span class="o"&gt;}&lt;/span&gt;,
      &lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  static async setupNotifeeChannel&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    await notifee.createChannel&lt;span class="o"&gt;({&lt;/span&gt;
      &lt;span class="nb"&gt;id&lt;/span&gt;: &lt;span class="s1"&gt;'default'&lt;/span&gt;,
      name: &lt;span class="s1"&gt;'Default Channel'&lt;/span&gt;,
      importance: AndroidImportance.HIGH,
    &lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="nb"&gt;export &lt;/span&gt;default NotificationService&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3️⃣ Initialize in App Entry (e.g., &lt;code&gt;App.js&lt;/code&gt;)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;import React, &lt;span class="o"&gt;{&lt;/span&gt; useEffect &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s1"&gt;'react'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import NotificationService from &lt;span class="s1"&gt;'./NotificationService'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nb"&gt;export &lt;/span&gt;default &lt;span class="k"&gt;function &lt;/span&gt;App&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  useEffect&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    NotificationService.requestPermission&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    NotificationService.setupNotifeeChannel&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    NotificationService.onMessageListener&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;, &lt;span class="o"&gt;[])&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &amp;lt;YourMainNavigator /&amp;gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  🧠 Step 3: Backend Setup to Send Push Notifications
&lt;/h3&gt;

&lt;p&gt;You can use &lt;strong&gt;Firebase Admin SDK&lt;/strong&gt; to send notifications from your backend.&lt;/p&gt;

&lt;h4&gt;
  
  
  1️⃣ Install Firebase Admin SDK
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;firebase-admin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2️⃣ Initialize Firebase in Your Backend
&lt;/h4&gt;

&lt;p&gt;Create a &lt;code&gt;firebaseAdmin.js&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;import admin from &lt;span class="s1"&gt;'firebase-admin'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import serviceAccount from &lt;span class="s1"&gt;'./serviceAccountKey.json'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; // download from Firebase Project Settings &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Service Accounts

admin.initializeApp&lt;span class="o"&gt;({&lt;/span&gt;
  credential: admin.credential.cert&lt;span class="o"&gt;(&lt;/span&gt;serviceAccount&lt;span class="o"&gt;)&lt;/span&gt;,
&lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nb"&gt;export &lt;/span&gt;default admin&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3️⃣ Send Notification API Example
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;import express from &lt;span class="s1"&gt;'express'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import admin from &lt;span class="s1"&gt;'./firebaseAdmin.js'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

const app &lt;span class="o"&gt;=&lt;/span&gt; express&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
app.use&lt;span class="o"&gt;(&lt;/span&gt;express.json&lt;span class="o"&gt;())&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

app.post&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/send-notification'&lt;/span&gt;, async &lt;span class="o"&gt;(&lt;/span&gt;req, res&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  try &lt;span class="o"&gt;{&lt;/span&gt;
    const &lt;span class="o"&gt;{&lt;/span&gt; token, title, body, data &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; req.body&lt;span class="p"&gt;;&lt;/span&gt;

    const message &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      token,
      notification: &lt;span class="o"&gt;{&lt;/span&gt; 
        title: title &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s1"&gt;'NotifyMeApp'&lt;/span&gt;, 
        body: body &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s1"&gt;'You have a new message waiting!'&lt;/span&gt; 
      &lt;span class="o"&gt;}&lt;/span&gt;,      data, // Optional custom data &lt;span class="k"&gt;for &lt;/span&gt;navigation
      android: &lt;span class="o"&gt;{&lt;/span&gt;
        notification: &lt;span class="o"&gt;{&lt;/span&gt;
          channelId: &lt;span class="s1"&gt;'default'&lt;/span&gt;,
          priority: &lt;span class="s1"&gt;'high'&lt;/span&gt;,
        &lt;span class="o"&gt;}&lt;/span&gt;,
      &lt;span class="o"&gt;}&lt;/span&gt;,
    &lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    const response &lt;span class="o"&gt;=&lt;/span&gt; await admin.messaging&lt;span class="o"&gt;()&lt;/span&gt;.send&lt;span class="o"&gt;(&lt;/span&gt;message&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    res.status&lt;span class="o"&gt;(&lt;/span&gt;200&lt;span class="o"&gt;)&lt;/span&gt;.json&lt;span class="o"&gt;({&lt;/span&gt; success: &lt;span class="nb"&gt;true&lt;/span&gt;, response &lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt; catch &lt;span class="o"&gt;(&lt;/span&gt;error&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    res.status&lt;span class="o"&gt;(&lt;/span&gt;500&lt;span class="o"&gt;)&lt;/span&gt;.json&lt;span class="o"&gt;({&lt;/span&gt; error: error.message &lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

app.listen&lt;span class="o"&gt;(&lt;/span&gt;4000, &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; console.log&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Server running on port 4000'&lt;/span&gt;&lt;span class="o"&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;Example Request:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;POST http://localhost:4000/send-notification
Content-Type: application/json

&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"token"&lt;/span&gt;: &lt;span class="s2"&gt;"fcm_device_token_here"&lt;/span&gt;,
  &lt;span class="s2"&gt;"title"&lt;/span&gt;: &lt;span class="s2"&gt;"NotifyMeApp"&lt;/span&gt;,
  &lt;span class="s2"&gt;"body"&lt;/span&gt;: &lt;span class="s2"&gt;"🎉 You just received a new notification!"&lt;/span&gt;,
  &lt;span class="s2"&gt;"data"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"targetScreen"&lt;/span&gt;: &lt;span class="s2"&gt;"Home"&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  🧭 Step 4: Handling Notification Taps (Navigation)
&lt;/h3&gt;

&lt;p&gt;To handle tap events and navigate to a specific screen:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;import notifee, &lt;span class="o"&gt;{&lt;/span&gt; EventType &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s1"&gt;'@notifee/react-native'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import &lt;span class="o"&gt;{&lt;/span&gt; navigationRef &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s1"&gt;'./NavigationService'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

notifee.onForegroundEvent&lt;span class="o"&gt;(({&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;, detail &lt;span class="o"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; EventType.PRESS &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; detail.notification&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    const targetScreen &lt;span class="o"&gt;=&lt;/span&gt; detail.notification.data?.targetScreen&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;targetScreen&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      navigationRef.current?.navigate&lt;span class="o"&gt;(&lt;/span&gt;targetScreen&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  ✅ Step 5: Test the Setup
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Run your app:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn android
&lt;span class="c"&gt;# or&lt;/span&gt;
yarn ios
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Copy the FCM token from the logs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use Postman or your backend API to send a test notification.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You should see a notification appear even when the app is in the background or foreground.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  🧾 Bonus Tips
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;For background notifications on Android, ensure you’ve set up a &lt;strong&gt;headless task&lt;/strong&gt; or &lt;strong&gt;background handler&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;On iOS, enable &lt;strong&gt;Push Notifications&lt;/strong&gt; and &lt;strong&gt;Background Modes → Remote notifications&lt;/strong&gt; in Xcode.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Store the FCM token in your backend to target specific users.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🎉 Wrapping Up
&lt;/h3&gt;

&lt;p&gt;You’ve now set up a complete &lt;strong&gt;FCM push notification flow&lt;/strong&gt; using &lt;strong&gt;Firebase&lt;/strong&gt;, &lt;strong&gt;Notifee&lt;/strong&gt;, and &lt;strong&gt;React Native&lt;/strong&gt; — including &lt;strong&gt;Firebase configuration&lt;/strong&gt;, &lt;strong&gt;mobile-side handling&lt;/strong&gt;, and &lt;strong&gt;backend message sending&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Push notifications enhance user engagement, and with Notifee, you can customize every part — from channels and sounds to advanced behaviors.&lt;/p&gt;




&lt;h3&gt;
  
  
  🔗 Continue to Part 2
&lt;/h3&gt;

&lt;p&gt;Read &lt;strong&gt;&lt;a href="https://dev.to/dainyjose/advanced-push-local-notifications-in-react-native-with-firebase-and-notifee-part-2-2mn6"&gt;Part 2: Advanced Push &amp;amp; Local Notifications …&lt;/a&gt;&lt;/strong&gt; for deeper exploration on triggers, actions, media/chat notifications, and handling every app state.&lt;/p&gt;




&lt;p&gt;✍️ Written by &lt;a href="https://www.linkedin.com/in/dainyjose" rel="noopener noreferrer"&gt;&lt;strong&gt;Dainy Jose&lt;/strong&gt;&lt;/a&gt; — React Native Mobile Application Developer with 3+ years of experience building cross-platform mobile apps using &lt;strong&gt;React Native (Expo, TypeScript, Redux)&lt;/strong&gt;. &lt;br&gt;
Currently expanding backend knowledge through the &lt;strong&gt;MERN Stack (MongoDB, Express.js, React.js, Node.js)&lt;/strong&gt; to create more efficient, full-stack mobile experiences.&lt;/p&gt;

&lt;p&gt;💼 &lt;strong&gt;Tech Stack:&lt;/strong&gt; React Native · TypeScript · Redux · Expo · Firebase · Node.js · Express.js · MongoDB · REST API · JWT · Jest · Google Maps · Razorpay · PayU · Agile · SDLC · Git · Bitbucket · Jira &lt;/p&gt;

&lt;p&gt;📬 &lt;strong&gt;Connect with me&lt;/strong&gt;:&lt;br&gt;
🌐 &lt;a href="https://dainyjose.github.io/my-portfolio/" rel="noopener noreferrer"&gt;Portfolio&lt;/a&gt;&lt;br&gt;
🔗 &lt;a href="https://www.linkedin.com/in/dainyjose" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;br&gt;
💻 &lt;a href="https://github.com/dainyjose" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>firebase</category>
      <category>fcm</category>
      <category>mobile</category>
    </item>
    <item>
      <title>🚀 Setting Up React Native (Expo Bare + TypeScript) Development Environment on macOS</title>
      <dc:creator>Dainy Jose</dc:creator>
      <pubDate>Mon, 22 Sep 2025 06:00:51 +0000</pubDate>
      <link>https://forem.com/dainyjose/setting-up-react-native-expo-bare-typescript-development-environment-on-macos-38hi</link>
      <guid>https://forem.com/dainyjose/setting-up-react-native-expo-bare-typescript-development-environment-on-macos-38hi</guid>
      <description>&lt;p&gt;If you’re starting with &lt;strong&gt;React Native (Expo Bare + TypeScript)&lt;/strong&gt; on macOS, you need a complete setup for Android and iOS development. This guide covers everything from installing prerequisites to running the app on simulators.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Reference Repo:&lt;/strong&gt; &lt;a href="https://github.com/dainyjose/rn-expo-typescript-bare-template.git" rel="noopener noreferrer"&gt;&lt;strong&gt;rn-expo-typescript-bare-template&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🔧 System Setup
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Install Homebrew
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/bin/bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Install Node &amp;amp; NPM
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;node
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Install Git
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Set up your Git identity:&lt;br&gt;
👉 &lt;a href="https://docs.github.com/en/get-started/git-basics/setting-your-username-in-git" rel="noopener noreferrer"&gt;Git username and email setup&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  4. Install Watchman
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;watchman
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  5. Install Java JDK (17)
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;openjdk@17
&lt;span class="nb"&gt;sudo ln&lt;/span&gt; &lt;span class="nt"&gt;-sfn&lt;/span&gt; /opt/homebrew/opt/openjdk@17/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-17.jdk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Add to your &lt;code&gt;~/.zshrc&lt;/code&gt; or &lt;code&gt;~/.bashrc&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;JAVA_HOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;/usr/libexec/java_home &lt;span class="nt"&gt;-v17&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$JAVA_HOME&lt;/span&gt;/bin:&lt;span class="nv"&gt;$PATH&lt;/span&gt;
&lt;span class="nb"&gt;source&lt;/span&gt; ~/.zshrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6. Install CocoaPods (for iOS)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;cocoapods
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7. Install Expo CLI
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; expo-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  8. Install VS Code
&lt;/h3&gt;

&lt;p&gt;👉 &lt;a href="https://code.visualstudio.com/download" rel="noopener noreferrer"&gt;Download VS Code&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  📱 Android &amp;amp; iOS Setup
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Android Studio
&lt;/h3&gt;

&lt;p&gt;👉 Download Android Studio&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.android.com/studio" rel="noopener noreferrer"&gt;Android Studio&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.android.com/studio/install" rel="noopener noreferrer"&gt;Android Studio: Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open &lt;strong&gt;Android Studio&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install &lt;strong&gt;SDKs &amp;amp; Emulator&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update local.properties inside &lt;code&gt;/android&lt;/code&gt; folder with your SDK path:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sdk.dir&lt;span class="o"&gt;=&lt;/span&gt;/Users/username/Library/Android/sdk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Xcode (for iOS)
&lt;/h3&gt;

&lt;p&gt;👉 &lt;a href="https://xcodereleases.com/" rel="noopener noreferrer"&gt;Download Xcode&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Switch versions if you maintain multiple Xcodes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;xcode-select &lt;span class="nt"&gt;-s&lt;/span&gt; /Applications/Xcode.app/Contents/Developer
&lt;span class="nb"&gt;sudo &lt;/span&gt;xcode-select &lt;span class="nt"&gt;-s&lt;/span&gt; ~/Downloads/Xcode.app/Contents/Developer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open &lt;code&gt;.xcworkspace&lt;/code&gt; in Xcode to build for iOS.&lt;/p&gt;




&lt;h2&gt;
  
  
  📂 Project Setup
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Clone the project:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone &amp;lt;your-repo-url&amp;gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;rn-expo-typescript-bare-template
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Install dependencies:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. For react-native-snap-carousel issue, import &lt;code&gt;ViewPropTypes&lt;/code&gt; manually:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;import &lt;span class="o"&gt;{&lt;/span&gt; ViewPropTypes &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s1"&gt;'deprecated-react-native-prop-types'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Update inside:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;react-native-snap-carousel/src/carousel&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;pagination&lt;/code&gt;, &lt;code&gt;paginationDot&lt;/code&gt;, &lt;code&gt;parallaxImage&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. iOS setup:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;ios
pod &lt;span class="nb"&gt;install
cd&lt;/span&gt; ..
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Run the app:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run ios
npm run android
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  ✅ Wrap-Up
&lt;/h3&gt;

&lt;p&gt;You now have a fully functional &lt;strong&gt;React Native (Expo Bare + TypeScript)&lt;/strong&gt; setup on macOS 🚀.&lt;br&gt;
This covers &lt;strong&gt;Node, JDK, Android Studio, Xcode, Git, Expo CLI, Pods, VS Code, and extra dev tools&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;📌 &lt;strong&gt;Reference Repo:&lt;/strong&gt; &lt;a href="https://github.com/dainyjose/rn-expo-typescript-bare-template.git" rel="noopener noreferrer"&gt;&lt;strong&gt;rn-expo-typescript-bare-template&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;✍️ Written by &lt;a href="https://www.linkedin.com/in/dainyjose" rel="noopener noreferrer"&gt;&lt;strong&gt;Dainy Jose&lt;/strong&gt;&lt;/a&gt; — React Native Mobile Application Developer with 3+ years of experience building cross-platform mobile apps using &lt;strong&gt;React Native (Expo, TypeScript, Redux)&lt;/strong&gt;. &lt;br&gt;
Currently expanding backend knowledge through the &lt;strong&gt;MERN Stack (MongoDB, Express.js, React.js, Node.js)&lt;/strong&gt; to create more efficient, full-stack mobile experiences.&lt;/p&gt;

&lt;p&gt;💼 &lt;strong&gt;Tech Stack:&lt;/strong&gt; React Native · TypeScript · Redux · Expo · Firebase · Node.js · Express.js · MongoDB · REST API · JWT · Jest · Google Maps · Razorpay · PayU · Agile · SDLC · Git · Bitbucket · Jira &lt;/p&gt;

&lt;p&gt;📬 &lt;strong&gt;Connect with me&lt;/strong&gt;:&lt;br&gt;
🌐 &lt;a href="https://dainyjose.github.io/my-portfolio/" rel="noopener noreferrer"&gt;Portfolio&lt;/a&gt;&lt;br&gt;
🔗 &lt;a href="https://www.linkedin.com/in/dainyjose" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;br&gt;
💻 &lt;a href="https://github.com/dainyjose" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>typescript</category>
      <category>mobile</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Edge-to-Edge Styling in React Native on Android 15</title>
      <dc:creator>Dainy Jose</dc:creator>
      <pubDate>Thu, 18 Sep 2025 07:11:30 +0000</pubDate>
      <link>https://forem.com/dainyjose/edge-to-edge-styling-in-react-native-on-android-15-2ihd</link>
      <guid>https://forem.com/dainyjose/edge-to-edge-styling-in-react-native-on-android-15-2ihd</guid>
      <description>&lt;p&gt;Google’s &lt;strong&gt;Android 15&lt;/strong&gt; pushes developers toward &lt;strong&gt;edge-to-edge design&lt;/strong&gt;, encouraging apps to extend content seamlessly behind the status and navigation bars.&lt;/p&gt;

&lt;p&gt;If you’re building with &lt;strong&gt;React Native&lt;/strong&gt;, you might have noticed layout issues or unexpected spacing after updating. This guide will show you how to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Enable immersive edge-to-edge layouts properly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Style your system bars for a modern look.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Apply a &lt;strong&gt;quick fix&lt;/strong&gt; if you just want your app working without redesigning right away.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🚀 Why Edge-to-Edge?
&lt;/h2&gt;

&lt;p&gt;By default, React Native apps avoid overlapping with system bars by applying safe padding. While functional, this can feel outdated compared to modern immersive apps.&lt;/p&gt;

&lt;p&gt;Benefits of edge-to-edge design:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Immersive user experience&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Maximized screen space&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Seamless blending with system UI&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  ⚙️ Step 1: Configure Android Window Settings
&lt;/h3&gt;

&lt;p&gt;Open your project’s &lt;code&gt;MainActivity.java&lt;/code&gt; (or &lt;code&gt;MainActivity.kt&lt;/code&gt;) and update the window in &lt;code&gt;onCreate&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;import android.os.Bundle&lt;span class="p"&gt;;&lt;/span&gt;
import androidx.core.view.WindowCompat&lt;span class="p"&gt;;&lt;/span&gt;

@Override
protected void onCreate&lt;span class="o"&gt;(&lt;/span&gt;Bundle savedInstanceState&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  super.onCreate&lt;span class="o"&gt;(&lt;/span&gt;null&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  // Enable edge-to-edge layout
  WindowCompat.setDecorFitsSystemWindows&lt;span class="o"&gt;(&lt;/span&gt;getWindow&lt;span class="o"&gt;()&lt;/span&gt;, &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tells Android not to inset your layout automatically, giving React Native full control of the screen.&lt;/p&gt;




&lt;h3&gt;
  
  
  🎨 Step 2: Use react-native-safe-area-context
&lt;/h3&gt;

&lt;p&gt;Install the package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add react-native-safe-area-context

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

&lt;/div&gt;



&lt;p&gt;Wrap your app with &lt;code&gt;SafeAreaProvider&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;import React from &lt;span class="s2"&gt;"react"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import &lt;span class="o"&gt;{&lt;/span&gt; SafeAreaProvider, SafeAreaView &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s2"&gt;"react-native-safe-area-context"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import &lt;span class="o"&gt;{&lt;/span&gt; Text, StyleSheet &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s2"&gt;"react-native"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nb"&gt;export &lt;/span&gt;default &lt;span class="k"&gt;function &lt;/span&gt;App&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;
    &amp;lt;SafeAreaProvider&amp;gt;
      &amp;lt;SafeAreaView
        &lt;span class="nv"&gt;style&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;styles.container&lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="nv"&gt;edges&lt;/span&gt;&lt;span class="o"&gt;={[&lt;/span&gt;&lt;span class="s2"&gt;"top"&lt;/span&gt;, &lt;span class="s2"&gt;"bottom"&lt;/span&gt;, &lt;span class="s2"&gt;"left"&lt;/span&gt;, &lt;span class="s2"&gt;"right"&lt;/span&gt;&lt;span class="o"&gt;]}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &amp;lt;Text &lt;span class="nv"&gt;style&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;styles.text&lt;span class="o"&gt;}&amp;gt;&lt;/span&gt;🌐 Edge-to-Edge &lt;span class="k"&gt;in &lt;/span&gt;Android 15&amp;lt;/Text&amp;gt;
      &amp;lt;/SafeAreaView&amp;gt;
    &amp;lt;/SafeAreaProvider&amp;gt;
  &lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

const styles &lt;span class="o"&gt;=&lt;/span&gt; StyleSheet.create&lt;span class="o"&gt;({&lt;/span&gt;
  container: &lt;span class="o"&gt;{&lt;/span&gt;
    flex: 1,
    backgroundColor: &lt;span class="s2"&gt;"#121212"&lt;/span&gt;, // Dark theme background
    justifyContent: &lt;span class="s2"&gt;"center"&lt;/span&gt;,
    alignItems: &lt;span class="s2"&gt;"center"&lt;/span&gt;,
  &lt;span class="o"&gt;}&lt;/span&gt;,
  text: &lt;span class="o"&gt;{&lt;/span&gt;
    color: &lt;span class="s2"&gt;"white"&lt;/span&gt;,
    fontSize: 20,
  &lt;span class="o"&gt;}&lt;/span&gt;,
&lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, &lt;code&gt;edges={["top", "bottom", "left", "right"]}&lt;/code&gt; ensures content adjusts safely while still extending edge-to-edge.&lt;/p&gt;




&lt;h3&gt;
  
  
  🎨 Step 3: Match System Bar Colors
&lt;/h3&gt;

&lt;p&gt;To avoid jarring contrasts, update system bar styling in &lt;code&gt;MainActivity.java&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;import android.os.Build&lt;span class="p"&gt;;&lt;/span&gt;
import android.view.WindowInsetsController&lt;span class="p"&gt;;&lt;/span&gt;
import android.graphics.Color&lt;span class="p"&gt;;&lt;/span&gt;

@Override
protected void onCreate&lt;span class="o"&gt;(&lt;/span&gt;Bundle savedInstanceState&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  super.onCreate&lt;span class="o"&gt;(&lt;/span&gt;null&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  WindowCompat.setDecorFitsSystemWindows&lt;span class="o"&gt;(&lt;/span&gt;getWindow&lt;span class="o"&gt;()&lt;/span&gt;, &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  // Make status &amp;amp; navigation bars transparent
  getWindow&lt;span class="o"&gt;()&lt;/span&gt;.setStatusBarColor&lt;span class="o"&gt;(&lt;/span&gt;Color.TRANSPARENT&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  getWindow&lt;span class="o"&gt;()&lt;/span&gt;.setNavigationBarColor&lt;span class="o"&gt;(&lt;/span&gt;Color.TRANSPARENT&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;Build.VERSION.SDK_INT &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; Build.VERSION_CODES.R&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    WindowInsetsController controller &lt;span class="o"&gt;=&lt;/span&gt; getWindow&lt;span class="o"&gt;()&lt;/span&gt;.getInsetsController&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;controller &lt;span class="o"&gt;!=&lt;/span&gt; null&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      controller.setSystemBarsAppearance&lt;span class="o"&gt;(&lt;/span&gt;
        WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS,
        WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS
      &lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensures your &lt;code&gt;status bar and navigation bar are transparent&lt;/code&gt; and icons adapt for visibility.&lt;/p&gt;




&lt;h3&gt;
  
  
  📱 Step 4: Test Across Themes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;✅ &lt;strong&gt;Light theme&lt;/strong&gt; → verify text/icons are visible against bright backgrounds.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;✅ &lt;strong&gt;Dark theme&lt;/strong&gt; → use transparent bars with white icons for contrast.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚡ Quick Fix: Opt-Out of Edge-to-Edge
&lt;/h2&gt;

&lt;p&gt;If your app’s layout &lt;strong&gt;breaks after upgrading to Android 15&lt;/strong&gt; and you don’t want to fix UI right away, you can temporarily &lt;strong&gt;opt out of edge-to-edge&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  1️⃣ Update AndroidManifest.xml
&lt;/h3&gt;

&lt;p&gt;Path: &lt;code&gt;android/app/src/main/AndroidManifest.xml&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&amp;lt;meta-data
    android:name&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"android.window.extensions.disableEdgeToEdge"&lt;/span&gt;
    android:value&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"true"&lt;/span&gt; /&amp;gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  2️⃣ Update styles.xml
&lt;/h3&gt;

&lt;p&gt;Path: &lt;code&gt;android/app/src/main/res/values/styles.xml&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&amp;lt;item &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"android:windowOptOutEdgeToEdgeEnforcement"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&amp;lt;/item&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ Done! Your app will behave like before, ignoring Android 15’s enforcement.&lt;/p&gt;

&lt;p&gt;⚠️ &lt;strong&gt;Note&lt;/strong&gt;: This should be treated as a &lt;strong&gt;temporary solution&lt;/strong&gt;. Long-term, adopt edge-to-edge for the best &lt;strong&gt;UX&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  🔎 Final Thoughts
&lt;/h3&gt;

&lt;p&gt;With Android 15, edge-to-edge styling is not just optional—it’s the new standard.&lt;/p&gt;

&lt;p&gt;You now have two paths:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Go immersive&lt;/strong&gt; → Adopt edge-to-edge with &lt;code&gt;WindowCompat&lt;/code&gt;, &lt;code&gt;react-native-safe-area-context&lt;/code&gt;, and transparent bars.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Play it safe&lt;/strong&gt; → Apply the quick fix until you’re ready to migrate.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Either way, your React Native app will be &lt;strong&gt;future-proof and visually polished&lt;/strong&gt;.&lt;/p&gt;




&lt;p&gt;💡 What’s your take? Do you prefer &lt;strong&gt;immersive full-screen layouts or classic padded designs&lt;/strong&gt; in React Native apps?&lt;/p&gt;




&lt;p&gt;✍️ Written by &lt;a href="https://www.linkedin.com/in/dainyjose" rel="noopener noreferrer"&gt;&lt;strong&gt;Dainy Jose&lt;/strong&gt;&lt;/a&gt; — React Native Mobile Application Developer with 3+ years of experience building cross-platform mobile apps using &lt;strong&gt;React Native (Expo, TypeScript, Redux)&lt;/strong&gt;. &lt;br&gt;
Currently expanding backend knowledge through the &lt;strong&gt;MERN Stack (MongoDB, Express.js, React.js, Node.js)&lt;/strong&gt; to create more efficient, full-stack mobile experiences.&lt;/p&gt;

&lt;p&gt;💼 &lt;strong&gt;Tech Stack:&lt;/strong&gt; React Native · TypeScript · Redux · Expo · Firebase · Node.js · Express.js · MongoDB · REST API · JWT · Jest · Google Maps · Razorpay · PayU · Agile · SDLC · Git · Bitbucket · Jira &lt;/p&gt;

&lt;p&gt;📬 &lt;strong&gt;Connect with me&lt;/strong&gt;:&lt;br&gt;
🌐 &lt;a href="https://dainyjose.github.io/my-portfolio/" rel="noopener noreferrer"&gt;Portfolio&lt;/a&gt;&lt;br&gt;
🔗 &lt;a href="https://www.linkedin.com/in/dainyjose" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;br&gt;
💻 &lt;a href="https://github.com/dainyjose" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>android</category>
      <category>mobile</category>
      <category>ui</category>
    </item>
  </channel>
</rss>
