<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Dainy Jose</title>
    <description>The latest articles on DEV Community by Dainy Jose (@dainyjose).</description>
    <link>https://dev.to/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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2361642%2F2d2d706c-5407-43f9-a162-574bce781b78.png</url>
      <title>DEV Community: Dainy Jose</title>
      <link>https://dev.to/dainyjose</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dainyjose"/>
    <language>en</language>
    <item>
      <title>Google Play Requires Android 16 (API Level 36) by August 31, 2026 — React Native Migration Guide</title>
      <dc:creator>Dainy Jose</dc:creator>
      <pubDate>Tue, 28 Jul 2026 17:10:01 +0000</pubDate>
      <link>https://dev.to/dainyjose/google-play-requires-android-16-api-level-36-by-august-31-2026-react-native-migration-guide-1d51</link>
      <guid>https://dev.to/dainyjose/google-play-requires-android-16-api-level-36-by-august-31-2026-react-native-migration-guide-1d51</guid>
      <description>&lt;p&gt;Google Play has announced that starting August 31, 2026, all new apps and app updates must target Android 16 (API level 36).&lt;/p&gt;

&lt;p&gt;If you're maintaining a React Native application, updating targetSdkVersion isn't just about passing Play Console checks—it's also about ensuring your app remains compatible with the latest Android platform changes.&lt;/p&gt;

&lt;p&gt;In this guide, I'll walk you through:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why this change matters&lt;/li&gt;
&lt;li&gt;How to update your React Native project&lt;/li&gt;
&lt;li&gt;Important Android 16 behavior changes&lt;/li&gt;
&lt;li&gt;A testing checklist before releasing&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Google Play Target API Requirement
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Starting August 31, 2026:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;New apps must target Android 16 (API level 36)&lt;/li&gt;
&lt;li&gt;App updates must also target Android 16 (API level 36)&lt;/li&gt;
&lt;li&gt;Existing apps must target at least Android 15 (API level 35) to remain discoverable by new users on devices running newer Android versions.&lt;/li&gt;
&lt;li&gt;Eligible developers can request an extension until November 1, 2026.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is part of Google's annual policy to ensure apps take advantage of the latest security, privacy, and platform improvements.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Does Google Increase the Target API Every Year?
&lt;/h2&gt;

&lt;p&gt;Targeting a newer Android version allows your app to benefit from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Improved security&lt;/li&gt;
&lt;li&gt;Better privacy protections&lt;/li&gt;
&lt;li&gt;Performance optimizations&lt;/li&gt;
&lt;li&gt;Modern background execution policies&lt;/li&gt;
&lt;li&gt;Better user experience across new devices&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While your app may still run on older Android versions, targeting the latest API ensures compatibility with current Android platform expectations.&lt;/p&gt;




&lt;h2&gt;
  
  
  Updating a React Native Project
&lt;/h2&gt;

&lt;p&gt;For most React Native applications, the migration is straightforward.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Install Android 16 SDK
&lt;/h4&gt;

&lt;p&gt;Open Android Studio → SDK Manager&lt;/p&gt;

&lt;p&gt;Install:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Android SDK Platform 36&lt;/li&gt;
&lt;li&gt;Android SDK Build Tools (latest)&lt;/li&gt;
&lt;li&gt;Android SDK Command-line Tools&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  2. Update compileSdk and targetSdk
&lt;/h4&gt;

&lt;p&gt;Depending on your project structure, update your Gradle configuration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight gradle"&gt;&lt;code&gt;&lt;span class="n"&gt;android&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;compileSdk&lt;/span&gt; &lt;span class="mi"&gt;36&lt;/span&gt;

    &lt;span class="n"&gt;defaultConfig&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;targetSdk&lt;/span&gt; &lt;span class="mi"&gt;36&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;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight gradle"&gt;&lt;code&gt;&lt;span class="n"&gt;compileSdkVersion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;36&lt;/span&gt;
&lt;span class="n"&gt;targetSdkVersion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;36&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: Updating to API 36 does not require changing your minSdkVersion. Your app can continue supporting older Android versions while targeting the latest Android release.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Update Android Gradle Plugin
&lt;/h4&gt;

&lt;p&gt;Use a version compatible with API 36.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight gradle"&gt;&lt;code&gt;&lt;span class="n"&gt;classpath&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"com.android.tools.build:gradle:8.6.1"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  4. Update Gradle
&lt;/h4&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;distributionUrl&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;https&lt;/span&gt;&lt;span class="se"&gt;\:&lt;/span&gt;&lt;span class="s"&gt;//services.gradle.org/distributions/gradle-8.13-bin.zip&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  5. Verify Kotlin Version
&lt;/h4&gt;

&lt;p&gt;Many recent React Native versions work well with Kotlin 2.x.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;kotlinVersion&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;2.0.21&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  6. Clean and Rebuild
&lt;/h4&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;android

./gradlew clean

&lt;span class="nb"&gt;cd&lt;/span&gt; ..

npx react-native run-android
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For release builds:&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;android

./gradlew assembleRelease
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Quick Migration Checklist
&lt;/h2&gt;

&lt;p&gt;Before uploading your app to Google Play, verify that you've completed the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Install Android SDK Platform 36&lt;/li&gt;
&lt;li&gt;[ ] Update &lt;code&gt;compileSdk&lt;/code&gt; to 36&lt;/li&gt;
&lt;li&gt;[ ] Update &lt;code&gt;targetSdk&lt;/code&gt; to 36&lt;/li&gt;
&lt;li&gt;[ ] Upgrade the Android Gradle Plugin (if required)&lt;/li&gt;
&lt;li&gt;[ ] Upgrade the Gradle Wrapper&lt;/li&gt;
&lt;li&gt;[ ] Verify Kotlin compatibility&lt;/li&gt;
&lt;li&gt;[ ] Update third-party native libraries&lt;/li&gt;
&lt;li&gt;[ ] Clean and rebuild the project&lt;/li&gt;
&lt;li&gt;[ ] Test on Android 16 devices or emulator&lt;/li&gt;
&lt;li&gt;[ ] Verify edge-to-edge layouts&lt;/li&gt;
&lt;li&gt;[ ] Generate a Release AAB&lt;/li&gt;
&lt;li&gt;[ ] Upload to Play Console and check for warnings&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Android 16 Behavior Changes You Should Know
&lt;/h2&gt;

&lt;p&gt;Simply updating &lt;code&gt;targetSdkVersion&lt;/code&gt; to 36 isn't enough. Android 16 introduces several platform behavior changes that may require code updates and additional testing.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Edge-to-Edge Is Mandatory
&lt;/h3&gt;

&lt;p&gt;One of the most noticeable changes is that apps targeting Android 16 can no longer opt out of edge-to-edge mode.&lt;/p&gt;

&lt;p&gt;This means your app content may extend behind the status and navigation bars unless properly handled.&lt;/p&gt;

&lt;p&gt;For React Native applications, test:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Safe areas&lt;/li&gt;
&lt;li&gt;Bottom navigation&lt;/li&gt;
&lt;li&gt;Headers&lt;/li&gt;
&lt;li&gt;Floating buttons&lt;/li&gt;
&lt;li&gt;Bottom sheets&lt;/li&gt;
&lt;li&gt;Keyboard interactions&lt;/li&gt;
&lt;li&gt;Full-screen screens&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're using react-native-safe-area-context, make sure you're on a recent version and verify layouts on both Android 15 and Android 16.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Large-Screen Support
&lt;/h3&gt;

&lt;p&gt;Android 16 improves the experience on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tablets&lt;/li&gt;
&lt;li&gt;Foldables&lt;/li&gt;
&lt;li&gt;Chromebooks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For displays with a smallest width of 600dp or greater, Android ignores several app restrictions, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Orientation locks&lt;/li&gt;
&lt;li&gt;Aspect ratio limits&lt;/li&gt;
&lt;li&gt;Resize restrictions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your app should adapt to different window sizes instead of assuming portrait mode.&lt;/p&gt;

&lt;p&gt;If your app hasn't been tested on tablets or foldables, now is a good time.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Background Scheduling Changes
&lt;/h3&gt;

&lt;p&gt;Android 16 changes how &lt;code&gt;scheduleAtFixedRate()&lt;/code&gt; behaves.&lt;/p&gt;

&lt;p&gt;Previously, if multiple scheduled executions were missed while the app wasn't active, Android could execute them all when the app resumed.&lt;/p&gt;

&lt;p&gt;Now, only one missed execution is triggered, helping reduce unnecessary background work.&lt;/p&gt;

&lt;p&gt;If your app performs periodic synchronization or recurring tasks, review this behavior.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Local Network Protection
&lt;/h3&gt;

&lt;p&gt;Android continues strengthening privacy.&lt;/p&gt;

&lt;p&gt;Apps communicating with devices on the local network—such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Smart home devices&lt;/li&gt;
&lt;li&gt;Printers&lt;/li&gt;
&lt;li&gt;IoT devices&lt;/li&gt;
&lt;li&gt;Local development servers&lt;/li&gt;
&lt;li&gt;Media casting devices&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;should begin testing against Android 16.&lt;/p&gt;

&lt;p&gt;Future Android versions will introduce explicit permissions for local network access.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Photo Picker Improvements
&lt;/h3&gt;

&lt;p&gt;If a user grants access to Selected Photos instead of the entire media library, Android 16 automatically pre-selects media created by your application.&lt;/p&gt;

&lt;p&gt;This creates a smoother user experience while maintaining user privacy.&lt;/p&gt;

&lt;p&gt;If your app uploads images or videos, test this flow carefully.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Background Jobs
&lt;/h3&gt;

&lt;p&gt;Android 16 introduces improvements to JobScheduler quotas.&lt;/p&gt;

&lt;p&gt;Apps using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;WorkManager&lt;/li&gt;
&lt;li&gt;JobScheduler&lt;/li&gt;
&lt;li&gt;Background uploads&lt;/li&gt;
&lt;li&gt;Background sync&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;should verify that jobs still execute as expected under different app states.&lt;/p&gt;




&lt;h2&gt;
  
  
  React Native Specific Things to Test
&lt;/h2&gt;

&lt;p&gt;After updating to API 36, I recommend verifying the following:&lt;/p&gt;

&lt;p&gt;✅ App launches correctly&lt;/p&gt;

&lt;p&gt;✅ Release APK/AAB builds successfully&lt;/p&gt;

&lt;p&gt;✅ Navigation works correctly&lt;/p&gt;

&lt;p&gt;✅ Safe areas are displayed properly&lt;/p&gt;

&lt;p&gt;✅ Status bar and navigation bar don't overlap content&lt;/p&gt;

&lt;p&gt;✅ Push notifications work&lt;/p&gt;

&lt;p&gt;✅ Deep links still open correctly&lt;/p&gt;

&lt;p&gt;✅ Camera functions normally&lt;/p&gt;

&lt;p&gt;✅ Image picker works&lt;/p&gt;

&lt;p&gt;✅ File uploads work&lt;/p&gt;

&lt;p&gt;✅ Location permissions behave correctly&lt;/p&gt;

&lt;p&gt;✅ Background tasks continue running&lt;/p&gt;

&lt;p&gt;✅ Payment SDKs function properly&lt;/p&gt;

&lt;p&gt;✅ Analytics events are still recorded&lt;/p&gt;

&lt;p&gt;✅ Tablets and foldables display correctly&lt;/p&gt;




&lt;h2&gt;
  
  
  Common Issues After Upgrading
&lt;/h2&gt;

&lt;p&gt;Depending on your project and dependencies, you may encounter:&lt;/p&gt;

&lt;h3&gt;
  
  
  Build failures
&lt;/h3&gt;

&lt;p&gt;These are commonly caused by outdated:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Android Gradle Plugin&lt;/li&gt;
&lt;li&gt;Gradle&lt;/li&gt;
&lt;li&gt;Kotlin&lt;/li&gt;
&lt;li&gt;AndroidX libraries&lt;/li&gt;
&lt;li&gt;Third-party library incompatibilities&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Common areas include:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Camera libraries&lt;/li&gt;
&lt;li&gt;Notification SDKs&lt;/li&gt;
&lt;li&gt;Background service libraries&lt;/li&gt;
&lt;li&gt;Payment SDKs&lt;/li&gt;
&lt;li&gt;Bluetooth libraries&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Always update dependencies before assuming Android 16 is the issue.&lt;/p&gt;

&lt;h3&gt;
  
  
  UI issues
&lt;/h3&gt;

&lt;p&gt;Because of mandatory edge-to-edge rendering, you may notice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Content behind the status bar&lt;/li&gt;
&lt;li&gt;Navigation bar overlap&lt;/li&gt;
&lt;li&gt;Incorrect bottom padding&lt;/li&gt;
&lt;li&gt;Keyboard layout problems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most of these can be resolved by properly handling window insets and safe areas.&lt;/p&gt;




&lt;h2&gt;
  
  
  Recommended React Native Versions
&lt;/h2&gt;

&lt;p&gt;While older React Native versions may still build, newer releases offer better compatibility with recent Android SDKs.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;React Native Version&lt;/th&gt;
&lt;th&gt;Recommendation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0.72 and below&lt;/td&gt;
&lt;td&gt;Consider upgrading before targeting API 36&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.73 – 0.78&lt;/td&gt;
&lt;td&gt;Test thoroughly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.79+&lt;/td&gt;
&lt;td&gt;Better support for modern Android SDKs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




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

&lt;p&gt;Updating to Android 16 (API level 36) is more than a Play Console requirement—it's an opportunity to modernize your app and ensure it works well across the latest Android devices.&lt;/p&gt;

&lt;p&gt;For most React Native projects, the migration is relatively simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Update your Android SDK&lt;/li&gt;
&lt;li&gt;Upgrade Gradle and the Android Gradle Plugin if necessary&lt;/li&gt;
&lt;li&gt;Set &lt;code&gt;compileSdk&lt;/code&gt; and &lt;code&gt;targetSdk&lt;/code&gt; to 36&lt;/li&gt;
&lt;li&gt;Test thoroughly on Android 16 devices&lt;/li&gt;
&lt;li&gt;Pay special attention to edge-to-edge layouts, background work, and large-screen support&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Android 16 isn't a massive migration for most React Native applications, but it does introduce several platform behaviors that deserve careful testing. Start upgrading early, keep your dependencies up to date, and validate your app on Android 16 devices before your production release.&lt;/p&gt;

&lt;p&gt;By migrating ahead of the August 31, 2026 deadline, you'll avoid Play Console submission issues and ensure your users receive the latest Android security, privacy, and performance improvements.&lt;/p&gt;




&lt;h3&gt;
  
  
  Useful Resources
&lt;/h3&gt;

&lt;p&gt;For more information, refer to the official Android documentation below:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.android.com/about/versions/16/behavior-changes-16" rel="noopener noreferrer"&gt;Android 16 Behavior Changes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.google.com/googleplay/android-developer/answer/11926878" rel="noopener noreferrer"&gt;Google Play Target API Requirements&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.android.com/about/versions/16" rel="noopener noreferrer"&gt;Android 16 Overview&lt;/a&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>android</category>
      <category>development</category>
      <category>mobile</category>
    </item>
    <item>
      <title>From Learning to Implementation: My Journey with Firebase Analytics &amp; GA4</title>
      <dc:creator>Dainy Jose</dc:creator>
      <pubDate>Mon, 27 Jul 2026 03:51:36 +0000</pubDate>
      <link>https://dev.to/dainyjose/from-learning-to-implementation-my-journey-with-firebase-analytics-ga4-1hjg</link>
      <guid>https://dev.to/dainyjose/from-learning-to-implementation-my-journey-with-firebase-analytics-ga4-1hjg</guid>
      <description>&lt;p&gt;Over the past few weeks, I've been focused on deepening my understanding of mobile analytics—not just by completing a course, but by putting those concepts into practice through hands-on implementation in React Native.&lt;/p&gt;

&lt;p&gt;Throughout this journey, I explored a wide range of topics, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Firebase Analytics integration&lt;/li&gt;
&lt;li&gt;Google Analytics 4 (GA4)&lt;/li&gt;
&lt;li&gt;Event planning and naming conventions&lt;/li&gt;
&lt;li&gt;Screen view tracking&lt;/li&gt;
&lt;li&gt;Custom events and custom definitions&lt;/li&gt;
&lt;li&gt;Key Events (Conversions)&lt;/li&gt;
&lt;li&gt;User properties and User ID&lt;/li&gt;
&lt;li&gt;Acquisition and campaign tracking&lt;/li&gt;
&lt;li&gt;Audience segmentation&lt;/li&gt;
&lt;li&gt;Ecommerce measurement&lt;/li&gt;
&lt;li&gt;Checkout funnel analysis&lt;/li&gt;
&lt;li&gt;Promotions and marketing attribution&lt;/li&gt;
&lt;li&gt;BigQuery integration&lt;/li&gt;
&lt;li&gt;Realtime reporting and DebugView&lt;/li&gt;
&lt;li&gt;Analytics validation and best practices&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One of the biggest lessons I learned is that &lt;strong&gt;analytics is much more than logging events&lt;/strong&gt;. A well-designed analytics strategy helps answer important questions about user behavior, feature adoption, user engagement, and conversion optimization. The quality of the insights you gain depends on having a well-planned event architecture, consistent naming conventions, and meaningful data collection from the very beginning.&lt;/p&gt;

&lt;p&gt;Completing this Udemy course gave me a strong foundation in Firebase Analytics and Google Analytics 4. Reinforcing that knowledge through hands-on implementation in React Native helped me better understand event planning, debugging, reporting, and analytics best practices for modern mobile applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Course Certificate
&lt;/h2&gt;

&lt;p&gt;I'm happy to have successfully completed the &lt;strong&gt;Firebase Analytics &amp;amp; Google Analytics 4 (GA4)&lt;/strong&gt; course on Udemy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Certificate:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://www.udemy.com/certificate/UC-4a23b92f-0857-4a75-83dd-ac186bdfdfbc" rel="noopener noreferrer"&gt;https://www.udemy.com/certificate/UC-4a23b92f-0857-4a75-83dd-ac186bdfdfbc&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The course covered both the fundamentals and advanced capabilities of mobile analytics, including GA4 reports, custom events, screen tracking, audiences, BigQuery integration, and data-driven decision making. It has been a valuable learning experience that strengthened both my theoretical understanding and practical implementation skills.&lt;/p&gt;

&lt;p&gt;Learning doesn't stop with earning a certificate. The real growth comes from building, experimenting, solving real-world problems, and continuously improving.&lt;/p&gt;

&lt;p&gt;If you're working with &lt;strong&gt;React Native&lt;/strong&gt;, &lt;strong&gt;Firebase Analytics&lt;/strong&gt;, or &lt;strong&gt;Google Analytics 4 (GA4)&lt;/strong&gt;, I'd love to hear about your experiences, best practices, or any challenges you've encountered. Let's learn and grow together as developers.&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>career</category>
      <category>reactnative</category>
      <category>firebase</category>
      <category>ga4</category>
    </item>
    <item>
      <title>Mastering GA4 for Mobile Apps — From Events to Business Insights</title>
      <dc:creator>Dainy Jose</dc:creator>
      <pubDate>Sun, 26 Jul 2026 17:29:12 +0000</pubDate>
      <link>https://dev.to/dainyjose/mastering-ga4-for-mobile-apps-from-events-to-business-insights-3n5l</link>
      <guid>https://dev.to/dainyjose/mastering-ga4-for-mobile-apps-from-events-to-business-insights-3n5l</guid>
      <description>&lt;p&gt;Integrating Firebase Analytics is an excellent first step toward understanding how users interact with your application—but it's only the beginning.&lt;/p&gt;

&lt;p&gt;The real value comes from &lt;strong&gt;Google Analytics 4 (GA4)&lt;/strong&gt;, where raw events are transformed into meaningful reports, dashboards, funnels, audiences, and business insights.&lt;/p&gt;

&lt;p&gt;GA4 helps developers, product managers, and marketers answer questions like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How are users discovering the app?&lt;/li&gt;
&lt;li&gt;Which features are used the most?&lt;/li&gt;
&lt;li&gt;Where do users drop off during important flows?&lt;/li&gt;
&lt;li&gt;Which campaigns drive the highest conversions?&lt;/li&gt;
&lt;li&gt;How can the overall user experience be improved?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this article, we'll explore the key GA4 features every mobile developer should understand.&lt;/p&gt;




&lt;h1&gt;
  
  
  Table of Contents
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;Realtime Report&lt;/li&gt;
&lt;li&gt;Reports Snapshot&lt;/li&gt;
&lt;li&gt;Events&lt;/li&gt;
&lt;li&gt;Custom Events&lt;/li&gt;
&lt;li&gt;Screen Tracking&lt;/li&gt;
&lt;li&gt;Custom Definitions&lt;/li&gt;
&lt;li&gt;Key Events (Conversions)&lt;/li&gt;
&lt;li&gt;Acquisition&lt;/li&gt;
&lt;li&gt;Engagement&lt;/li&gt;
&lt;li&gt;Monetization&lt;/li&gt;
&lt;li&gt;Ecommerce&lt;/li&gt;
&lt;li&gt;Checkout Journey&lt;/li&gt;
&lt;li&gt;Promotions&lt;/li&gt;
&lt;li&gt;Campaign Tracking&lt;/li&gt;
&lt;li&gt;Audiences&lt;/li&gt;
&lt;li&gt;BigQuery Integration&lt;/li&gt;
&lt;li&gt;User ID&lt;/li&gt;
&lt;li&gt;Best Practices&lt;/li&gt;
&lt;li&gt;Final Thoughts&lt;/li&gt;
&lt;/ol&gt;




&lt;h1&gt;
  
  
  1. Realtime Report
&lt;/h1&gt;

&lt;p&gt;The &lt;strong&gt;Realtime Report&lt;/strong&gt; is one of the most useful tools during development.&lt;/p&gt;

&lt;p&gt;It allows you to verify that your application is sending analytics events correctly within seconds.&lt;/p&gt;

&lt;p&gt;You can quickly validate actions such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;App opens&lt;/li&gt;
&lt;li&gt;Screen views&lt;/li&gt;
&lt;li&gt;User sign in&lt;/li&gt;
&lt;li&gt;Button clicks&lt;/li&gt;
&lt;li&gt;Item views&lt;/li&gt;
&lt;li&gt;Add to cart&lt;/li&gt;
&lt;li&gt;Checkout&lt;/li&gt;
&lt;li&gt;Purchases&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of waiting for reports to process, the Realtime Report provides immediate feedback while testing your implementation.&lt;/p&gt;




&lt;h1&gt;
  
  
  2. Reports Snapshot
&lt;/h1&gt;

&lt;p&gt;The &lt;strong&gt;Reports Snapshot&lt;/strong&gt; provides a high-level overview of your application's performance.&lt;/p&gt;

&lt;p&gt;Some of the metrics available include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Active users&lt;/li&gt;
&lt;li&gt;New users&lt;/li&gt;
&lt;li&gt;Sessions&lt;/li&gt;
&lt;li&gt;User engagement&lt;/li&gt;
&lt;li&gt;Event count&lt;/li&gt;
&lt;li&gt;Top screens&lt;/li&gt;
&lt;li&gt;Revenue&lt;/li&gt;
&lt;li&gt;Retention trends&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of it as the health dashboard for your application.&lt;/p&gt;




&lt;h1&gt;
  
  
  3. Events
&lt;/h1&gt;

&lt;p&gt;Everything in GA4 revolves around &lt;strong&gt;events&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Every user interaction—whether automatic or custom—is recorded as an event.&lt;/p&gt;

&lt;p&gt;Common examples include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;login
sign_up
view_item
select_item
search
add_to_cart
begin_checkout
purchase
share
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By consistently tracking meaningful events, you create the foundation for all GA4 reports.&lt;/p&gt;




&lt;h1&gt;
  
  
  4. Custom Events
&lt;/h1&gt;

&lt;p&gt;Not every application fits predefined event categories.&lt;/p&gt;

&lt;p&gt;Custom events allow you to measure actions that are unique to your application's functionality.&lt;/p&gt;

&lt;p&gt;Examples include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;profile_completed
subscription_started
subscription_cancelled
feature_used
feedback_submitted
payment_failed
notification_opened
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Custom events become even more powerful when combined with parameters and custom definitions.&lt;/p&gt;




&lt;h1&gt;
  
  
  5. Screen Tracking
&lt;/h1&gt;

&lt;p&gt;Understanding how users navigate your application is essential.&lt;/p&gt;

&lt;p&gt;Typical screens include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Home&lt;/li&gt;
&lt;li&gt;Search&lt;/li&gt;
&lt;li&gt;Details&lt;/li&gt;
&lt;li&gt;Profile&lt;/li&gt;
&lt;li&gt;Settings&lt;/li&gt;
&lt;li&gt;Notifications&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Screen tracking helps answer questions such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which screens receive the most visits?&lt;/li&gt;
&lt;li&gt;Where do users spend the most time?&lt;/li&gt;
&lt;li&gt;Which screens have the highest exit rate?&lt;/li&gt;
&lt;li&gt;What navigation paths are most common?&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  6. Custom Definitions
&lt;/h1&gt;

&lt;p&gt;Event parameters are collected with your events, but to use them in GA4 reports, you often need to register them as &lt;strong&gt;Custom Definitions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User Role&lt;/li&gt;
&lt;li&gt;Subscription Plan&lt;/li&gt;
&lt;li&gt;Content Category&lt;/li&gt;
&lt;li&gt;Payment Method&lt;/li&gt;
&lt;li&gt;App Version&lt;/li&gt;
&lt;li&gt;Device Type&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Custom definitions make it possible to filter, segment, and analyze reports using business-specific information.&lt;/p&gt;




&lt;h1&gt;
  
  
  7. Key Events (Conversions)
&lt;/h1&gt;

&lt;p&gt;Some user actions are more valuable than others.&lt;/p&gt;

&lt;p&gt;GA4 allows you to mark important events as &lt;strong&gt;Key Events&lt;/strong&gt; (formerly called Conversions).&lt;/p&gt;

&lt;p&gt;Examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User Registration&lt;/li&gt;
&lt;li&gt;Purchase&lt;/li&gt;
&lt;li&gt;Subscription&lt;/li&gt;
&lt;li&gt;Form Submission&lt;/li&gt;
&lt;li&gt;Profile Completion&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tracking Key Events helps measure the success of your application's goals.&lt;/p&gt;




&lt;h1&gt;
  
  
  8. Acquisition
&lt;/h1&gt;

&lt;p&gt;The Acquisition reports answer an important question:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where are your users coming from?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;GA4 categorizes traffic sources such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Organic Search&lt;/li&gt;
&lt;li&gt;Direct&lt;/li&gt;
&lt;li&gt;Social Media&lt;/li&gt;
&lt;li&gt;Referral&lt;/li&gt;
&lt;li&gt;Email Campaigns&lt;/li&gt;
&lt;li&gt;Paid Advertising&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These reports help marketing teams understand which channels bring the most valuable users.&lt;/p&gt;




&lt;h1&gt;
  
  
  9. Engagement
&lt;/h1&gt;

&lt;p&gt;Engagement reports focus on how users interact with your application after they arrive.&lt;/p&gt;

&lt;p&gt;Important metrics include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Engagement time&lt;/li&gt;
&lt;li&gt;Engaged sessions&lt;/li&gt;
&lt;li&gt;Screen views&lt;/li&gt;
&lt;li&gt;Event count&lt;/li&gt;
&lt;li&gt;Returning users&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Strong engagement usually indicates a better user experience.&lt;/p&gt;




&lt;h1&gt;
  
  
  10. Monetization
&lt;/h1&gt;

&lt;p&gt;For applications that generate revenue, the Monetization reports provide valuable financial insights.&lt;/p&gt;

&lt;p&gt;You can monitor:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Revenue&lt;/li&gt;
&lt;li&gt;Purchases&lt;/li&gt;
&lt;li&gt;Refunds&lt;/li&gt;
&lt;li&gt;Average Revenue Per User (ARPU)&lt;/li&gt;
&lt;li&gt;Purchase trends&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These reports help evaluate business performance over time.&lt;/p&gt;




&lt;h1&gt;
  
  
  11. Ecommerce
&lt;/h1&gt;

&lt;p&gt;GA4 provides built-in support for ecommerce tracking.&lt;/p&gt;

&lt;p&gt;Recommended ecommerce events include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;view_item&lt;/li&gt;
&lt;li&gt;view_item_list&lt;/li&gt;
&lt;li&gt;select_item&lt;/li&gt;
&lt;li&gt;add_to_cart&lt;/li&gt;
&lt;li&gt;remove_from_cart&lt;/li&gt;
&lt;li&gt;begin_checkout&lt;/li&gt;
&lt;li&gt;add_payment_info&lt;/li&gt;
&lt;li&gt;purchase&lt;/li&gt;
&lt;li&gt;refund&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using Google's recommended event names ensures better compatibility with GA4 reports.&lt;/p&gt;




&lt;h1&gt;
  
  
  12. Checkout Journey
&lt;/h1&gt;

&lt;p&gt;One of GA4's most useful capabilities is identifying where users abandon the purchase flow.&lt;/p&gt;

&lt;p&gt;Example funnel:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;View Item
      ↓
Add to Cart
      ↓
Begin Checkout
      ↓
Add Payment Information
      ↓
Purchase
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Analyzing drop-off at each step helps identify friction points and improve conversion rates.&lt;/p&gt;




&lt;h1&gt;
  
  
  13. Promotions
&lt;/h1&gt;

&lt;p&gt;If your application displays promotional content, GA4 can measure its effectiveness.&lt;/p&gt;

&lt;p&gt;Examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Promotional banners&lt;/li&gt;
&lt;li&gt;Featured content&lt;/li&gt;
&lt;li&gt;Coupons&lt;/li&gt;
&lt;li&gt;Seasonal offers&lt;/li&gt;
&lt;li&gt;Limited-time campaigns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can compare impressions, clicks, and resulting conversions to understand which promotions perform best.&lt;/p&gt;




&lt;h1&gt;
  
  
  14. Campaign Tracking
&lt;/h1&gt;

&lt;p&gt;Campaign tracking allows you to measure marketing performance using UTM parameters.&lt;/p&gt;

&lt;p&gt;Common campaign parameters include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;utm_source&lt;/li&gt;
&lt;li&gt;utm_medium&lt;/li&gt;
&lt;li&gt;utm_campaign&lt;/li&gt;
&lt;li&gt;utm_content&lt;/li&gt;
&lt;li&gt;utm_term&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This makes it easier to evaluate app installs and user engagement from different marketing channels.&lt;/p&gt;




&lt;h1&gt;
  
  
  15. Audiences
&lt;/h1&gt;

&lt;p&gt;GA4 enables you to create dynamic audiences based on user behavior.&lt;/p&gt;

&lt;p&gt;Examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;New Users&lt;/li&gt;
&lt;li&gt;Returning Users&lt;/li&gt;
&lt;li&gt;Active Users&lt;/li&gt;
&lt;li&gt;Inactive Users&lt;/li&gt;
&lt;li&gt;Subscribers&lt;/li&gt;
&lt;li&gt;High-Value Users&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These audiences can be used for reporting, personalization, and advertising integrations such as Google Ads.&lt;/p&gt;




&lt;h1&gt;
  
  
  16. BigQuery Integration
&lt;/h1&gt;

&lt;p&gt;One of GA4's most powerful features is its native BigQuery integration.&lt;/p&gt;

&lt;p&gt;Instead of relying only on standard reports, you gain access to raw event-level data.&lt;/p&gt;

&lt;p&gt;This enables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SQL analysis&lt;/li&gt;
&lt;li&gt;Custom dashboards&lt;/li&gt;
&lt;li&gt;Funnel analysis&lt;/li&gt;
&lt;li&gt;Cohort analysis&lt;/li&gt;
&lt;li&gt;Machine learning&lt;/li&gt;
&lt;li&gt;Predictive analytics&lt;/li&gt;
&lt;li&gt;Data warehouse integration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For organizations working with large datasets, BigQuery unlocks virtually unlimited analytical possibilities.&lt;/p&gt;




&lt;h1&gt;
  
  
  17. User ID
&lt;/h1&gt;

&lt;p&gt;By default, GA4 identifies users using device or browser identifiers.&lt;/p&gt;

&lt;p&gt;This means a single person using multiple devices may appear as multiple users.&lt;/p&gt;

&lt;p&gt;Without User ID:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;One User
     ↓
Multiple Devices
     ↓
Multiple User Records
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With User ID:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;One User
     ↓
Multiple Devices
     ↓
Single Unified Identity
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Implementing User ID provides more accurate cross-device reporting while respecting your application's authentication and privacy policies.&lt;/p&gt;




&lt;h1&gt;
  
  
  Best Practices
&lt;/h1&gt;

&lt;p&gt;To build a scalable analytics implementation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use GA4 recommended event names whenever possible.&lt;/li&gt;
&lt;li&gt;Keep event names consistent across platforms.&lt;/li&gt;
&lt;li&gt;Track only meaningful user interactions.&lt;/li&gt;
&lt;li&gt;Register important parameters as Custom Definitions.&lt;/li&gt;
&lt;li&gt;Mark business-critical actions as Key Events.&lt;/li&gt;
&lt;li&gt;Validate implementations using the Realtime Report.&lt;/li&gt;
&lt;li&gt;Create an event tracking plan before development begins.&lt;/li&gt;
&lt;li&gt;Periodically review reports and remove unused events.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A well-planned analytics strategy produces cleaner reports and more actionable insights.&lt;/p&gt;




&lt;h1&gt;
  
  
  Final Thoughts
&lt;/h1&gt;

&lt;p&gt;Google Analytics 4 is much more than a reporting dashboard—it's a comprehensive analytics platform that helps teams understand user behavior, measure business outcomes, and continuously improve digital experiences.&lt;/p&gt;

&lt;p&gt;The quality of your analytics depends on the quality of your event strategy. By designing meaningful events, capturing useful parameters, and leveraging GA4's reporting capabilities, you can turn raw data into insights that drive better product decisions.&lt;/p&gt;

&lt;p&gt;In the next article, we'll explore best practices for designing a scalable event architecture and implementing Firebase Analytics and GA4 effectively in React Native applications.&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>ga4</category>
      <category>firebase</category>
      <category>reactnative</category>
      <category>analytics</category>
    </item>
    <item>
      <title>Firebase Analytics in React Native — Complete Implementation Guide</title>
      <dc:creator>Dainy Jose</dc:creator>
      <pubDate>Sat, 25 Jul 2026 16:40:49 +0000</pubDate>
      <link>https://dev.to/dainyjose/firebase-analytics-in-react-native-complete-implementation-guide-4ec4</link>
      <guid>https://dev.to/dainyjose/firebase-analytics-in-react-native-complete-implementation-guide-4ec4</guid>
      <description>&lt;p&gt;Analytics is one of the most valuable tools you can add to a mobile application. While building features is important, understanding how users interact with those features is what helps improve the overall user experience.&lt;/p&gt;

&lt;p&gt;Many developers assume analytics is just about logging a few events. In reality, a well-planned analytics strategy provides insights that help product teams make informed decisions, identify user behavior patterns, and optimize the application over time.&lt;/p&gt;

&lt;p&gt;In this guide, we'll walk through setting up Firebase Analytics in a React Native application and cover the essential tracking techniques every mobile developer should know.&lt;/p&gt;




&lt;h1&gt;
  
  
  Why Firebase Analytics?
&lt;/h1&gt;

&lt;p&gt;Firebase Analytics is Google's free analytics solution for mobile and web applications. It is deeply integrated with Google Analytics 4 (GA4), making it easy to collect user behavior data and transform it into actionable insights.&lt;/p&gt;

&lt;p&gt;Some of its key capabilities include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Screen tracking&lt;/li&gt;
&lt;li&gt;Automatic event collection&lt;/li&gt;
&lt;li&gt;Custom event tracking&lt;/li&gt;
&lt;li&gt;User properties&lt;/li&gt;
&lt;li&gt;User ID support&lt;/li&gt;
&lt;li&gt;Audience creation&lt;/li&gt;
&lt;li&gt;Funnel analysis&lt;/li&gt;
&lt;li&gt;Real-time monitoring&lt;/li&gt;
&lt;li&gt;BigQuery integration&lt;/li&gt;
&lt;li&gt;Seamless integration with GA4&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Whether you're building a small application or a large-scale production product, Firebase Analytics provides a solid foundation for understanding user engagement.&lt;/p&gt;




&lt;h1&gt;
  
  
  Prerequisites
&lt;/h1&gt;

&lt;p&gt;Before getting started, make sure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A React Native project&lt;/li&gt;
&lt;li&gt;A Firebase project&lt;/li&gt;
&lt;li&gt;Android Studio and Xcode configured&lt;/li&gt;
&lt;li&gt;Firebase configured for both Android and iOS&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Installing Firebase Analytics
&lt;/h1&gt;

&lt;p&gt;Install the required 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 &lt;span class="nb"&gt;install&lt;/span&gt; @react-native-firebase/app
npm &lt;span class="nb"&gt;install&lt;/span&gt; @react-native-firebase/analytics
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For iOS, install CocoaPods dependencies.&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
pod &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Firebase Configuration
&lt;/h1&gt;

&lt;p&gt;Download the Firebase configuration files from the Firebase Console.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;android/app/google-services.json&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plist"&gt;&lt;code&gt;&lt;span class="l"&gt;ios/GoogleService-Info.plist&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Place each file in its respective platform directory.&lt;/p&gt;

&lt;p&gt;After completing the platform-specific configuration, rebuild the application.&lt;/p&gt;




&lt;h1&gt;
  
  
  Import Analytics
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;analytics&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@react-native-firebase/analytics&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Log Your First Event
&lt;/h1&gt;

&lt;p&gt;Once Analytics is initialized, you can log events.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;analytics&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;logEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;app_open&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Although Firebase automatically records several events, custom events allow you to track interactions specific to your application.&lt;/p&gt;




&lt;h1&gt;
  
  
  Track Screen Views
&lt;/h1&gt;

&lt;p&gt;Understanding which screens users visit most frequently is essential for improving navigation and user experience.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;analytics&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;logScreenView&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;screen_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Home&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;screen_class&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;HomeScreen&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Screen tracking helps answer questions such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which screens receive the most traffic?&lt;/li&gt;
&lt;li&gt;How long do users stay on each screen?&lt;/li&gt;
&lt;li&gt;Which navigation paths are most common?&lt;/li&gt;
&lt;li&gt;Where do users leave the application?&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Track Custom Events
&lt;/h1&gt;

&lt;p&gt;Custom events capture meaningful user interactions that are unique to your application.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;analytics&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;logEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;add_to_cart&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;product_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;123&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;category&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mobile&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some commonly used events include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;login&lt;/li&gt;
&lt;li&gt;sign_up&lt;/li&gt;
&lt;li&gt;search&lt;/li&gt;
&lt;li&gt;view_item&lt;/li&gt;
&lt;li&gt;select_item&lt;/li&gt;
&lt;li&gt;add_to_cart&lt;/li&gt;
&lt;li&gt;remove_from_cart&lt;/li&gt;
&lt;li&gt;begin_checkout&lt;/li&gt;
&lt;li&gt;purchase&lt;/li&gt;
&lt;li&gt;share&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Whenever possible, prefer GA4's recommended event names to improve reporting and compatibility.&lt;/p&gt;




&lt;h1&gt;
  
  
  Set User Properties
&lt;/h1&gt;

&lt;p&gt;User properties help segment users based on shared characteristics.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;analytics&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;setUserProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;membership&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Premium&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Examples of useful user properties include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Membership level&lt;/li&gt;
&lt;li&gt;User role&lt;/li&gt;
&lt;li&gt;Subscription plan&lt;/li&gt;
&lt;li&gt;Preferred language&lt;/li&gt;
&lt;li&gt;Country&lt;/li&gt;
&lt;li&gt;App version&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These properties can later be used to build audiences and analyze specific user segments.&lt;/p&gt;




&lt;h1&gt;
  
  
  Set User ID
&lt;/h1&gt;

&lt;p&gt;If users authenticate within your application, you can associate analytics data with a unique user identifier.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;analytics&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;setUserId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This enables more accurate cross-session reporting while respecting your application's privacy policies.&lt;/p&gt;




&lt;h1&gt;
  
  
  Debug Analytics Events
&lt;/h1&gt;

&lt;p&gt;During development, it's important to verify that events are being received correctly.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;adb shell setprop debug.firebase.analytics.app your.package.name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After enabling debug mode, open Firebase DebugView to monitor incoming events in near real time.&lt;/p&gt;




&lt;h1&gt;
  
  
  Verify Your Events
&lt;/h1&gt;

&lt;p&gt;Before releasing your application, always confirm that events appear correctly in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Firebase DebugView&lt;/li&gt;
&lt;li&gt;GA4 Realtime Report&lt;/li&gt;
&lt;li&gt;GA4 Events Report&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Never assume an event is working simply because your code executes successfully. Always verify it within the analytics dashboard.&lt;/p&gt;




&lt;h1&gt;
  
  
  Common Mistakes to Avoid
&lt;/h1&gt;

&lt;p&gt;Avoid these common implementation issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Logging too many unnecessary events&lt;/li&gt;
&lt;li&gt;Using inconsistent event names&lt;/li&gt;
&lt;li&gt;Missing important event parameters&lt;/li&gt;
&lt;li&gt;Tracking the same screen multiple times&lt;/li&gt;
&lt;li&gt;Ignoring Firebase DebugView during testing&lt;/li&gt;
&lt;li&gt;Changing event names frequently after release&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A consistent event naming strategy makes reports easier to maintain as your application grows.&lt;/p&gt;




&lt;h1&gt;
  
  
  Best Practices
&lt;/h1&gt;

&lt;p&gt;Here are a few recommendations that have proven effective:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Follow GA4 recommended event names whenever possible.&lt;/li&gt;
&lt;li&gt;Keep event names short and descriptive.&lt;/li&gt;
&lt;li&gt;Include meaningful parameters with every custom event.&lt;/li&gt;
&lt;li&gt;Define an event tracking plan before implementation.&lt;/li&gt;
&lt;li&gt;Validate events in DebugView before releasing updates.&lt;/li&gt;
&lt;li&gt;Use User Properties for segmentation instead of creating duplicate events.&lt;/li&gt;
&lt;li&gt;Keep analytics implementation centralized using helper functions or services.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Following these practices results in cleaner dashboards and more reliable insights.&lt;/p&gt;




&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Firebase Analytics is much more than an event logging library—it's the foundation for understanding how users interact with your application.&lt;/p&gt;

&lt;p&gt;By implementing screen tracking, custom events, user properties, and proper validation, you can build an analytics strategy that scales as your application grows.&lt;/p&gt;

&lt;p&gt;In the next article, we'll explore how Google Analytics 4 (GA4) transforms these events into dashboards, funnels, audiences, and actionable business insights.&lt;/p&gt;

&lt;p&gt;If you're using Firebase Analytics in your React Native projects, feel free to share your favorite implementation tips or best practices in the comments.&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>analytics</category>
      <category>mobile</category>
    </item>
    <item>
      <title>Understanding OWASP Mobile Top 10 (2025): A Guide for Android &amp; iOS Developers</title>
      <dc:creator>Dainy Jose</dc:creator>
      <pubDate>Sun, 28 Jun 2026 16:32:01 +0000</pubDate>
      <link>https://dev.to/dainyjose/understanding-owasp-mobile-top-10-2025-a-guide-for-android-ios-developers-371p</link>
      <guid>https://dev.to/dainyjose/understanding-owasp-mobile-top-10-2025-a-guide-for-android-ios-developers-371p</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Disclaimer: This article summarizes the concepts I learned while studying the OWASP Mobile Top 10 (2025) and includes additional references from official OWASP documentation to help fellow developers get started.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Mobile applications have become an essential part of our daily lives, handling everything from banking and healthcare to shopping and communication. As mobile apps process increasingly sensitive data, security must be considered throughout the development lifecycle—not as an afterthought.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;OWASP Mobile Top 10 (2025)&lt;/strong&gt; is a community-driven list of the most critical security risks affecting Android and iOS applications. It helps developers, security engineers, and organizations understand common vulnerabilities and implement best practices to build more secure mobile apps.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why OWASP Mobile Top 10 Matters
&lt;/h2&gt;

&lt;p&gt;Many security incidents occur because of simple mistakes such as storing sensitive data insecurely, trusting client-side validation, or using outdated cryptographic algorithms.&lt;/p&gt;

&lt;p&gt;By understanding these risks early, developers can design applications that are more resilient against attacks like reverse engineering, credential theft, data leakage, and unauthorized access.&lt;/p&gt;




&lt;h1&gt;
  
  
  The OWASP Mobile Top 10 (2025)
&lt;/h1&gt;

&lt;h2&gt;
  
  
  M1: Improper Credential Usage
&lt;/h2&gt;

&lt;p&gt;Applications should never hardcode API keys, passwords, or authentication tokens. Credentials stored insecurely can be extracted through reverse engineering and used to access backend services.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use OAuth 2.0/OpenID Connect&lt;/li&gt;
&lt;li&gt;Store secrets in Android Keystore or iOS Keychain&lt;/li&gt;
&lt;li&gt;Use short-lived access tokens and refresh token rotation&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  M2: Inadequate Supply Chain Security
&lt;/h2&gt;

&lt;p&gt;Modern apps depend heavily on third-party SDKs and open-source libraries. Outdated or untrusted dependencies can introduce vulnerabilities or malicious code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vet third-party vendors&lt;/li&gt;
&lt;li&gt;Maintain an SBOM (Software Bill of Materials)&lt;/li&gt;
&lt;li&gt;Automate dependency scanning&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  M3: Insecure Authentication &amp;amp; Authorization
&lt;/h2&gt;

&lt;p&gt;Weak passwords, missing MFA, or poor server-side authorization can allow attackers to gain unauthorized access.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Strong password policies&lt;/li&gt;
&lt;li&gt;Platform-native biometrics&lt;/li&gt;
&lt;li&gt;Server-side authorization checks&lt;/li&gt;
&lt;li&gt;Role-Based Access Control (RBAC)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  M4: Insufficient Input &amp;amp; Output Validation
&lt;/h2&gt;

&lt;p&gt;Failing to validate user input can lead to injection attacks, data corruption, or unexpected application behavior.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Validate all client and server inputs&lt;/li&gt;
&lt;li&gt;Sanitize outputs&lt;/li&gt;
&lt;li&gt;Use parameterized queries&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  M5: Insecure Communication
&lt;/h2&gt;

&lt;p&gt;Sensitive information should always be protected while traveling across networks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TLS 1.2 or TLS 1.3&lt;/li&gt;
&lt;li&gt;Certificate validation&lt;/li&gt;
&lt;li&gt;Certificate pinning&lt;/li&gt;
&lt;li&gt;Disable insecure protocols&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  M6: Inadequate Privacy Controls
&lt;/h2&gt;

&lt;p&gt;Collecting excessive user data or sharing personal information without consent can violate user trust and regulations such as GDPR and CCPA.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Data minimization&lt;/li&gt;
&lt;li&gt;Explicit user consent&lt;/li&gt;
&lt;li&gt;Encrypt sensitive data&lt;/li&gt;
&lt;li&gt;Transparent privacy policies&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  M7: Insufficient Binary Protection
&lt;/h2&gt;

&lt;p&gt;Mobile apps can be reverse engineered, modified, or repackaged if they lack binary protection.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Code obfuscation (R8/ProGuard)&lt;/li&gt;
&lt;li&gt;Runtime integrity verification&lt;/li&gt;
&lt;li&gt;Signature validation&lt;/li&gt;
&lt;li&gt;Frida/Xposed detection&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  M8: Security Misconfiguration
&lt;/h2&gt;

&lt;p&gt;Debug logging, insecure build configurations, and exposed endpoints often leak valuable information to attackers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Disable debug logs in production&lt;/li&gt;
&lt;li&gt;Secure release builds&lt;/li&gt;
&lt;li&gt;Regular configuration reviews&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  M9: Insecure Data Storage
&lt;/h2&gt;

&lt;p&gt;Sensitive information stored on the device should always be encrypted and protected.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Android Keystore&lt;/li&gt;
&lt;li&gt;iOS Keychain/Secure Enclave&lt;/li&gt;
&lt;li&gt;Encrypted SharedPreferences&lt;/li&gt;
&lt;li&gt;Avoid storing sensitive data unnecessarily&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  M10: Insufficient Cryptography
&lt;/h2&gt;

&lt;p&gt;Using outdated algorithms such as MD5 or weak random number generators can compromise data confidentiality.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Argon2 or bcrypt for password hashing&lt;/li&gt;
&lt;li&gt;AES-GCM for encryption&lt;/li&gt;
&lt;li&gt;SecureRandom for cryptographic randomness&lt;/li&gt;
&lt;li&gt;Regular cryptographic reviews&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Security Is More Than Writing Secure Code
&lt;/h1&gt;

&lt;p&gt;Building secure mobile applications requires a layered approach that includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Secure architecture&lt;/li&gt;
&lt;li&gt;Secure coding practices&lt;/li&gt;
&lt;li&gt;Dependency management&lt;/li&gt;
&lt;li&gt;Continuous security testing&lt;/li&gt;
&lt;li&gt;Runtime protection&lt;/li&gt;
&lt;li&gt;Monitoring and incident response&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Frameworks like &lt;strong&gt;OWASP MASVS (Mobile Application Security Verification Standard)&lt;/strong&gt; and &lt;strong&gt;OWASP MSTG (Mobile Security Testing Guide)&lt;/strong&gt; provide practical guidance for implementing and verifying these security controls.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recommended Security Tools
&lt;/h2&gt;

&lt;p&gt;Some useful tools for securing mobile applications include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MobSF&lt;/strong&gt; – Mobile application security testing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OWASP ZAP&lt;/strong&gt; – API and dynamic security testing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SonarQube&lt;/strong&gt; &amp;amp; &lt;strong&gt;Semgrep&lt;/strong&gt; – Static code analysis&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gitleaks&lt;/strong&gt; – Secret detection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OWASP Dependency-Check&lt;/strong&gt; – Dependency vulnerability scanning&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CycloneDX / SPDX&lt;/strong&gt; – Software Bill of Materials (SBOM)&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;The OWASP Mobile Top 10 (2025) is not just a list of vulnerabilities—it's a roadmap for building secure Android and iOS applications. Whether you're a mobile developer, security engineer, or architect, understanding these risks helps you create applications that protect user data, resist modern attack techniques, and meet industry security standards.&lt;/p&gt;

&lt;p&gt;Security is an ongoing process. Integrating secure design, continuous testing, and regular updates into the development lifecycle is the key to building trustworthy mobile applications.&lt;/p&gt;




&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;If you're interested in learning more about mobile application security, I highly recommend this course:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;OWASP Mobile Top 10 2025: Android &amp;amp; iOS App Security&lt;/strong&gt; by Dr. Amar Massoud&lt;/li&gt;
&lt;li&gt;🎓 &lt;strong&gt;My Certificate of Completion:&lt;/strong&gt; &lt;a href="https://ude.my/UC-492454b2-dbfa-4753-a9e8-35d6722b91c1" rel="noopener noreferrer"&gt;https://ude.my/UC-492454b2-dbfa-4753-a9e8-35d6722b91c1&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can also explore these official OWASP resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OWASP Mobile Application Security: &lt;a href="https://owasp.org/www-project-mobile-top-10/" rel="noopener noreferrer"&gt;https://owasp.org/www-project-mobile-top-10/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;OWASP MASVS: &lt;a href="https://mas.owasp.org/MASVS/" rel="noopener noreferrer"&gt;https://mas.owasp.org/MASVS/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;OWASP MSTG: &lt;a href="https://mas.owasp.org/MSTG/" rel="noopener noreferrer"&gt;https://mas.owasp.org/MSTG/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Thank you for reading! If you found this article useful, feel free to ❤️ like it, leave a comment, or share your experience with mobile application security.&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>security</category>
      <category>owasp</category>
      <category>mobile</category>
      <category>developer</category>
    </item>
    <item>
      <title>Building Picture-in-Picture (PiP) Mode in React Native with Expo and TypeScript</title>
      <dc:creator>Dainy Jose</dc:creator>
      <pubDate>Mon, 01 Jun 2026 17:06:29 +0000</pubDate>
      <link>https://dev.to/dainyjose/building-picture-in-picture-pip-mode-in-react-native-with-expo-and-typescript-af6</link>
      <guid>https://dev.to/dainyjose/building-picture-in-picture-pip-mode-in-react-native-with-expo-and-typescript-af6</guid>
      <description>&lt;p&gt;Picture-in-Picture (PiP) mode is one of the most useful features for media-based mobile applications. It allows users to continue watching video content while navigating outside the app.&lt;/p&gt;

&lt;p&gt;In this article, we will build a modern React Native PiP Mode Proof of Concept using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React Native&lt;/li&gt;
&lt;li&gt;Expo&lt;/li&gt;
&lt;li&gt;TypeScript&lt;/li&gt;
&lt;li&gt;react-native-video&lt;/li&gt;
&lt;li&gt;Native Android PiP APIs&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  What is Picture-in-Picture (PiP)?
&lt;/h3&gt;

&lt;p&gt;Picture-in-Picture mode allows a video player to continue playing inside a small floating window while users interact with other applications.&lt;/p&gt;

&lt;p&gt;Popular apps using PiP:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;YouTube&lt;/li&gt;
&lt;li&gt;Google Meet&lt;/li&gt;
&lt;li&gt;Netflix&lt;/li&gt;
&lt;li&gt;WhatsApp Video Calls&lt;/li&gt;
&lt;/ul&gt;




&lt;h4&gt;
  
  
  Final Result
&lt;/h4&gt;

&lt;p&gt;Features implemented:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Floating mini-player&lt;/li&gt;
&lt;li&gt;Background playback&lt;/li&gt;
&lt;li&gt;Auto-enter PiP mode&lt;/li&gt;
&lt;li&gt;Manual PiP trigger&lt;/li&gt;
&lt;li&gt;Modern UI&lt;/li&gt;
&lt;li&gt;Reusable custom hook&lt;/li&gt;
&lt;li&gt;Native Android integration&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Source Code&lt;/p&gt;

&lt;p&gt;The complete source code for this project is available on GitHub:&lt;/p&gt;

&lt;p&gt;🔗 GitHub Repository: &lt;a href="https://github.com/dainyjose/pip-video-player-mobile" rel="noopener noreferrer"&gt;https://github.com/dainyjose/pip-video-player-mobile&lt;/a&gt;&lt;/p&gt;




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

&lt;h4&gt;
  
  
  Expo Project Setup
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx create-expo-app react-native-pip-poc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Move into 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;&lt;span class="nb"&gt;cd &lt;/span&gt;react-native-pip-poc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Install Dependencies
&lt;/h3&gt;

&lt;p&gt;Install video package:&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-video
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Project Structure
&lt;/h3&gt;

&lt;p&gt;Instead of putting everything inside &lt;code&gt;App.tsx&lt;/code&gt;, use a scalable architecture.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
 ├── components/
 │    ├── MiniPlayer.tsx
 │    ├── PipButton.tsx
 │    ├── PipStatus.tsx
 │    └── VideoPlayer.tsx
 │
 ├── hooks/
 │    └── usePictureInPicture.ts
 │
 ├── constants/
 │    └── video.ts
 │
 ├── screens/
 │    └── PlayerScreen.tsx
 │
 └── types/
      └── video.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This keeps the code reusable and production-ready.&lt;/p&gt;




&lt;h3&gt;
  
  
  Android PiP Configuration
&lt;/h3&gt;

&lt;h4&gt;
  
  
  AndroidManifest.xml
&lt;/h4&gt;

&lt;p&gt;Open:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;android/app/src/main/AndroidManifest.xml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;activity&lt;/span&gt;
  &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;".MainActivity"&lt;/span&gt;
  &lt;span class="na"&gt;android:supportsPictureInPicture=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;
  &lt;span class="na"&gt;android:configChanges=&lt;/span&gt;&lt;span class="s"&gt;"keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"&lt;/span&gt;
  &lt;span class="na"&gt;android:launchMode=&lt;/span&gt;&lt;span class="s"&gt;"singleTask"&lt;/span&gt;
  &lt;span class="na"&gt;android:windowSoftInputMode=&lt;/span&gt;&lt;span class="s"&gt;"adjustResize"&lt;/span&gt;
  &lt;span class="na"&gt;android:exported=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This enables native Android PiP support.&lt;/p&gt;




&lt;h3&gt;
  
  
  Configure MainActivity.kt
&lt;/h3&gt;

&lt;p&gt;Open:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;android/app/src/main/java/.../MainActivity.kt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;onUserLeaveHint&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onUserLeaveHint&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="nc"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;VERSION&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;SDK_INT&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nc"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;VERSION_CODES&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;O&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;params&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
            &lt;span class="nc"&gt;PictureInPictureParams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Builder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setAspectRatio&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Rational&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="nf"&gt;enterPictureInPictureMode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&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;This automatically enters PiP mode when the app moves to the background.&lt;/p&gt;




&lt;h3&gt;
  
  
  Create Reusable PiP Hook
&lt;/h3&gt;

&lt;h3&gt;
  
  
  usePictureInPicture.ts
&lt;/h3&gt;

&lt;p&gt;Instead of writing all logic directly inside the screen, create a reusable hook.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useCallback&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useRef&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Platform&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-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;VideoRef&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native-video&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;usePictureInPicture&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;videoRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;RefObject&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;VideoRef&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="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;loadedRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRef&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&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;pendingPipRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRef&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pipActive&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setPipActive&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;paused&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setPaused&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&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;enterPip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCallback&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;delays&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
      &lt;span class="nx"&gt;Platform&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;OS&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ios&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="mi"&gt;250&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;700&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1200&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="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="nx"&gt;delays&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;setTimeout&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="nx"&gt;videoRef&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;enterPictureInPicture&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;delay&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;activateFloatingPlayer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;pendingPipRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nf"&gt;setPaused&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&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;loadedRef&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="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;enterPip&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;paused&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;setPaused&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;pipActive&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;setPipActive&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;loadedRef&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;activateFloatingPlayer&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;Benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;reusable logic&lt;/li&gt;
&lt;li&gt;cleaner screens&lt;/li&gt;
&lt;li&gt;easier maintenance&lt;/li&gt;
&lt;li&gt;scalable architecture&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Build Video Player Component
&lt;/h3&gt;

&lt;h4&gt;
  
  
  VideoPlayer.tsx
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Video&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native-video&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Video&lt;/span&gt;
  &lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;videoRef&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;VIDEO_SOURCE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;video&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;resizeMode&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"contain"&lt;/span&gt;
  &lt;span class="na"&gt;paused&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;paused&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;controls&lt;/span&gt;
  &lt;span class="na"&gt;playInBackground&lt;/span&gt;
  &lt;span class="na"&gt;playWhenInactive&lt;/span&gt;
  &lt;span class="na"&gt;enterPictureInPictureOnLeave&lt;/span&gt;
  &lt;span class="na"&gt;ignoreSilentSwitch&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"ignore"&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Important PiP props:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Prop&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;playInBackground&lt;/td&gt;
&lt;td&gt;Continue playback in background&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;playWhenInactive&lt;/td&gt;
&lt;td&gt;Allow inactive playback&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;enterPictureInPictureOnLeave&lt;/td&gt;
&lt;td&gt;Auto-enter PiP&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h3&gt;
  
  
  Auto PiP on Background
&lt;/h3&gt;

&lt;p&gt;Inside the screen:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sub&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;AppState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;change&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;state&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;state&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;background&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;activateFloatingPlayer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&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;This creates a YouTube-like experience.&lt;/p&gt;




&lt;h3&gt;
  
  
  Modern UI Layout
&lt;/h3&gt;

&lt;p&gt;Instead of basic buttons, create:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Player card&lt;/li&gt;
&lt;li&gt;Floating mini-player&lt;/li&gt;
&lt;li&gt;Status cards&lt;/li&gt;
&lt;li&gt;Dark streaming UI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;playerCard&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;VideoPlayer&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;PipButton&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;PipStatus&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Running the Project
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Android
&lt;/h4&gt;



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

&lt;/div&gt;






&lt;h3&gt;
  
  
  Important Notes
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Expo Go Limitation
&lt;/h4&gt;

&lt;p&gt;Expo Go may not fully support native PiP functionality.&lt;/p&gt;

&lt;p&gt;Use native builds instead.&lt;/p&gt;




&lt;h3&gt;
  
  
  Common Issues
&lt;/h3&gt;

&lt;h4&gt;
  
  
  PiP Not Starting
&lt;/h4&gt;

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

&lt;ul&gt;
&lt;li&gt;Android version &amp;gt;= 8&lt;/li&gt;
&lt;li&gt;Manifest configuration&lt;/li&gt;
&lt;li&gt;Native build usage&lt;/li&gt;
&lt;li&gt;Video loaded state&lt;/li&gt;
&lt;/ul&gt;




&lt;h4&gt;
  
  
  App Crashes
&lt;/h4&gt;

&lt;p&gt;Verify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;correct MainActivity.kt imports&lt;/li&gt;
&lt;li&gt;react-native-video installation&lt;/li&gt;
&lt;li&gt;Android SDK compatibility&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Future Improvements
&lt;/h3&gt;

&lt;p&gt;This PoC can be extended with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Custom PiP controls&lt;/li&gt;
&lt;li&gt;Live streaming&lt;/li&gt;
&lt;li&gt;Video call PiP&lt;/li&gt;
&lt;li&gt;Draggable mini-player&lt;/li&gt;
&lt;li&gt;Media session controls&lt;/li&gt;
&lt;li&gt;Netflix-style player UI&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;Picture-in-Picture mode significantly improves user experience for media applications.&lt;/p&gt;

&lt;p&gt;With React Native, Expo, and native Android APIs, we can build scalable and modern PiP experiences similar to YouTube and Netflix.&lt;/p&gt;

&lt;p&gt;This project demonstrates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;native Android PiP integration&lt;/li&gt;
&lt;li&gt;modular React Native architecture&lt;/li&gt;
&lt;li&gt;reusable hooks&lt;/li&gt;
&lt;li&gt;background playback handling&lt;/li&gt;
&lt;li&gt;scalable UI structure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can now extend this implementation into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OTT applications&lt;/li&gt;
&lt;li&gt;Video conferencing apps&lt;/li&gt;
&lt;li&gt;Live class platforms&lt;/li&gt;
&lt;li&gt;Social media video apps&lt;/li&gt;
&lt;li&gt;Streaming platforms&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>android</category>
      <category>ios</category>
      <category>mobile</category>
    </item>
    <item>
      <title>Complete CI/CD Guide for React Native Apps Using GitHub Actions</title>
      <dc:creator>Dainy Jose</dc:creator>
      <pubDate>Mon, 11 May 2026 08:43:26 +0000</pubDate>
      <link>https://dev.to/dainyjose/complete-cicd-guide-for-react-native-apps-using-github-actions-4hh1</link>
      <guid>https://dev.to/dainyjose/complete-cicd-guide-for-react-native-apps-using-github-actions-4hh1</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Automating builds, testing, and deployments can save hours of manual work in React Native projects. This article explains how to set up a practical CI/CD pipeline for Android and iOS apps using GitHub Actions.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;As React Native projects grow, manual release processes become difficult.&lt;/p&gt;

&lt;p&gt;Developers often spend time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;generating APKs manually&lt;/li&gt;
&lt;li&gt;updating versions&lt;/li&gt;
&lt;li&gt;testing release builds&lt;/li&gt;
&lt;li&gt;uploading builds to stores&lt;/li&gt;
&lt;li&gt;fixing environment issues&lt;/li&gt;
&lt;li&gt;handling signing configurations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This process becomes repetitive and error-prone.&lt;/p&gt;

&lt;p&gt;That’s where CI/CD helps.&lt;/p&gt;

&lt;p&gt;A proper CI/CD pipeline can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;automate builds&lt;/li&gt;
&lt;li&gt;reduce human errors&lt;/li&gt;
&lt;li&gt;improve release consistency&lt;/li&gt;
&lt;li&gt;speed up deployments&lt;/li&gt;
&lt;li&gt;help teams collaborate efficiently&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this article, I’ll explain how I set up CI/CD for React Native apps using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub Actions&lt;/li&gt;
&lt;li&gt;Fastlane&lt;/li&gt;
&lt;li&gt;Android &amp;amp; iOS workflows&lt;/li&gt;
&lt;li&gt;environment configurations&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  What is CI/CD?
&lt;/h1&gt;

&lt;p&gt;CI/CD stands for:&lt;/p&gt;

&lt;h2&gt;
  
  
  Continuous Integration (CI)
&lt;/h2&gt;

&lt;p&gt;Automatically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;validating code&lt;/li&gt;
&lt;li&gt;running tests&lt;/li&gt;
&lt;li&gt;checking builds&lt;/li&gt;
&lt;li&gt;detecting issues early&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;whenever code is pushed.&lt;/p&gt;




&lt;h2&gt;
  
  
  Continuous Deployment/Delivery (CD)
&lt;/h2&gt;

&lt;p&gt;Automatically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;generating release builds&lt;/li&gt;
&lt;li&gt;distributing apps&lt;/li&gt;
&lt;li&gt;deploying to stores&lt;/li&gt;
&lt;li&gt;handling release workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This reduces manual release effort.&lt;/p&gt;




&lt;h1&gt;
  
  
  Why CI/CD Matters in React Native
&lt;/h1&gt;

&lt;p&gt;React Native projects involve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JavaScript&lt;/li&gt;
&lt;li&gt;Android native code&lt;/li&gt;
&lt;li&gt;iOS native code&lt;/li&gt;
&lt;li&gt;multiple environments&lt;/li&gt;
&lt;li&gt;third-party SDKs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without automation, release management becomes difficult.&lt;/p&gt;




&lt;h1&gt;
  
  
  Tools You Can Use
&lt;/h1&gt;

&lt;h2&gt;
  
  
  1. GitHub Actions
&lt;/h2&gt;

&lt;p&gt;Used for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;workflow automation&lt;/li&gt;
&lt;li&gt;build pipelines&lt;/li&gt;
&lt;li&gt;running scripts&lt;/li&gt;
&lt;li&gt;deployment triggers&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  2. Fastlane
&lt;/h2&gt;

&lt;p&gt;Used for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Android Play Store uploads&lt;/li&gt;
&lt;li&gt;TestFlight uploads&lt;/li&gt;
&lt;li&gt;signing management&lt;/li&gt;
&lt;li&gt;screenshots and metadata&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  3. Firebase Crashlytics
&lt;/h2&gt;

&lt;p&gt;Used for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;crash monitoring&lt;/li&gt;
&lt;li&gt;release issue tracking&lt;/li&gt;
&lt;li&gt;production debugging&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Recommended Project Setup
&lt;/h1&gt;

&lt;p&gt;Before setting up CI/CD, ensure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- separate environments
- proper signing setup
- release build testing
- version management
- secure secret storage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This prevents many pipeline issues later.&lt;/p&gt;




&lt;h1&gt;
  
  
  Step 1: Create GitHub Actions Workflow
&lt;/h1&gt;

&lt;p&gt;Inside your project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.github/workflows/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;android-build.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Android Build&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout Code&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Setup Node&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install Dependencies&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm install&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build Android APK&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;cd android&lt;/span&gt;
          &lt;span class="s"&gt;./gradlew assembleRelease&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This automatically generates Android release builds.&lt;/p&gt;




&lt;h1&gt;
  
  
  Step 2: Configure Secrets Securely
&lt;/h1&gt;

&lt;p&gt;Never store:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API keys&lt;/li&gt;
&lt;li&gt;keystore passwords&lt;/li&gt;
&lt;li&gt;certificates&lt;/li&gt;
&lt;li&gt;signing configs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;inside the repository.&lt;/p&gt;

&lt;p&gt;Use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GitHub Repository Secrets
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;signing passwords&lt;/li&gt;
&lt;li&gt;Firebase configs&lt;/li&gt;
&lt;li&gt;Play Store credentials&lt;/li&gt;
&lt;li&gt;App Store credentials&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Step 3: Android Signing Setup
&lt;/h1&gt;

&lt;p&gt;For Android release builds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;android/app/release.keystore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Configure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight gradle"&gt;&lt;code&gt;&lt;span class="n"&gt;signingConfigs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;android/app/build.gradle
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight gradle"&gt;&lt;code&gt;&lt;span class="n"&gt;release&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;storeFile&lt;/span&gt; &lt;span class="nf"&gt;file&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MYAPP_UPLOAD_STORE_FILE&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
   &lt;span class="n"&gt;storePassword&lt;/span&gt; &lt;span class="n"&gt;MYAPP_UPLOAD_STORE_PASSWORD&lt;/span&gt;
   &lt;span class="n"&gt;keyAlias&lt;/span&gt; &lt;span class="n"&gt;MYAPP_UPLOAD_KEY_ALIAS&lt;/span&gt;
   &lt;span class="n"&gt;keyPassword&lt;/span&gt; &lt;span class="n"&gt;MYAPP_UPLOAD_KEY_PASSWORD&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Step 4: iOS CI/CD Setup
&lt;/h1&gt;

&lt;p&gt;iOS setup is slightly more complex because of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;certificates&lt;/li&gt;
&lt;li&gt;provisioning profiles&lt;/li&gt;
&lt;li&gt;code signing&lt;/li&gt;
&lt;li&gt;macOS runners&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;GitHub Actions requires:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;macos-latest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;for iOS builds.&lt;/p&gt;




&lt;h1&gt;
  
  
  Step 5: Fastlane Integration
&lt;/h1&gt;

&lt;p&gt;Fastlane simplifies deployments.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bundle &lt;span class="nb"&gt;exec &lt;/span&gt;fastlane init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Android Deployment Example
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;lane&lt;/span&gt; &lt;span class="ss"&gt;:android_release&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;gradle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;task: &lt;/span&gt;&lt;span class="s2"&gt;"assembleRelease"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  iOS Deployment Example
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;lane&lt;/span&gt; &lt;span class="ss"&gt;:ios_release&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;build_app&lt;/span&gt;
  &lt;span class="n"&gt;upload_to_testflight&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This automates deployment significantly.&lt;/p&gt;




&lt;h1&gt;
  
  
  Step 6: Automate Version Management
&lt;/h1&gt;

&lt;p&gt;One common problem in mobile releases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;incorrect build numbers&lt;/li&gt;
&lt;li&gt;duplicate version codes&lt;/li&gt;
&lt;li&gt;store upload failures&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Automate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Android versionCode&lt;/li&gt;
&lt;li&gt;iOS build number&lt;/li&gt;
&lt;li&gt;semantic versions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;inside CI/CD pipelines.&lt;/p&gt;

&lt;p&gt;This reduces release mistakes.&lt;/p&gt;




&lt;h1&gt;
  
  
  Step 7: Run Quality Checks Before Builds
&lt;/h1&gt;

&lt;p&gt;Before generating release builds, I recommend running:&lt;/p&gt;

&lt;h2&gt;
  
  
  Lint
&lt;/h2&gt;



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

&lt;/div&gt;






&lt;h2&gt;
  
  
  TypeScript Check
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx tsc &lt;span class="nt"&gt;--noEmit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Tests
&lt;/h2&gt;



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

&lt;/div&gt;



&lt;p&gt;This prevents broken builds from reaching production.&lt;/p&gt;




&lt;h1&gt;
  
  
  Handling Multiple Environments
&lt;/h1&gt;

&lt;p&gt;In production apps, we usually have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- development
- staging
- production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I manage environments using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.env.development
.env.production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;with separate workflows.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;github.ref == 'refs/heads/main'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;for production deployments.&lt;/p&gt;




&lt;h1&gt;
  
  
  Common CI/CD Issues I Faced
&lt;/h1&gt;

&lt;h1&gt;
  
  
  1. Android Build Works Locally but Fails in CI
&lt;/h1&gt;

&lt;p&gt;Usually caused by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;missing SDK versions&lt;/li&gt;
&lt;li&gt;Gradle mismatch&lt;/li&gt;
&lt;li&gt;Java version issues&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  2. iOS Signing Failures
&lt;/h1&gt;

&lt;p&gt;Most common problem in iOS pipelines.&lt;/p&gt;

&lt;p&gt;Usually related to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;certificates&lt;/li&gt;
&lt;li&gt;provisioning profiles&lt;/li&gt;
&lt;li&gt;Apple Developer configuration&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  3. Environment Variables Missing
&lt;/h1&gt;

&lt;p&gt;Sometimes release builds fail because CI environments do not load &lt;code&gt;.env&lt;/code&gt; correctly.&lt;/p&gt;

&lt;p&gt;Always validate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;workflow variables&lt;/li&gt;
&lt;li&gt;secret mappings&lt;/li&gt;
&lt;li&gt;build configurations&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  4. Slow Build Times
&lt;/h1&gt;

&lt;p&gt;Large React Native projects can become slow in CI.&lt;/p&gt;

&lt;p&gt;Build times can be improved using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dependency caching&lt;/li&gt;
&lt;li&gt;Gradle caching&lt;/li&gt;
&lt;li&gt;npm caching&lt;/li&gt;
&lt;li&gt;selective workflows&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  My Recommended CI/CD Practices
&lt;/h1&gt;

&lt;h2&gt;
  
  
  1. Always Test Release Builds
&lt;/h2&gt;

&lt;p&gt;Debug builds are not enough.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Keep Secrets Secure
&lt;/h2&gt;

&lt;p&gt;Never commit sensitive credentials.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Automate Repetitive Tasks
&lt;/h2&gt;

&lt;p&gt;Anything repeated manually should probably be automated.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Separate Development &amp;amp; Production Pipelines
&lt;/h2&gt;

&lt;p&gt;This prevents accidental releases.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Monitor Releases Properly
&lt;/h2&gt;

&lt;p&gt;Use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Crashlytics&lt;/li&gt;
&lt;li&gt;logs&lt;/li&gt;
&lt;li&gt;analytics&lt;/li&gt;
&lt;li&gt;release monitoring&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;for production stability.&lt;/p&gt;




&lt;h1&gt;
  
  
  Benefits of Implementing CI/CD
&lt;/h1&gt;

&lt;p&gt;After setting up CI/CD:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;releases became faster&lt;/li&gt;
&lt;li&gt;fewer manual mistakes happened&lt;/li&gt;
&lt;li&gt;deployments became more consistent&lt;/li&gt;
&lt;li&gt;onboarding developers became easier&lt;/li&gt;
&lt;li&gt;debugging release issues improved&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most importantly, the release process became predictable.&lt;/p&gt;




&lt;h1&gt;
  
  
  Final Thoughts
&lt;/h1&gt;

&lt;p&gt;CI/CD may initially feel complicated in React Native projects.&lt;/p&gt;

&lt;p&gt;Especially because mobile apps involve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Android builds&lt;/li&gt;
&lt;li&gt;iOS signing&lt;/li&gt;
&lt;li&gt;native dependencies&lt;/li&gt;
&lt;li&gt;environment management&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But once configured properly, it saves a huge amount of development time.&lt;/p&gt;

&lt;p&gt;Even a basic CI/CD setup can dramatically improve team productivity and release quality.&lt;/p&gt;

&lt;p&gt;Start simple.&lt;br&gt;
Then gradually automate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;testing&lt;/li&gt;
&lt;li&gt;builds&lt;/li&gt;
&lt;li&gt;deployments&lt;/li&gt;
&lt;li&gt;versioning&lt;/li&gt;
&lt;li&gt;monitoring&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;over time.&lt;/p&gt;




&lt;h2&gt;
  
  
  How are you managing CI/CD in your React Native projects?
&lt;/h2&gt;

&lt;p&gt;Are you using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub Actions&lt;/li&gt;
&lt;li&gt;Fastlane&lt;/li&gt;
&lt;li&gt;Bitrise&lt;/li&gt;
&lt;li&gt;CircleCI&lt;/li&gt;
&lt;li&gt;Expo EAS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Share your workflow in the comments 👇&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>cicd</category>
      <category>github</category>
      <category>reactnative</category>
      <category>tutorial</category>
    </item>
    <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://dev.to/dainyjose/preparing-your-ios-app-for-the-upcoming-sdk-requirements-april-2026-3l7f</link>
      <guid>https://dev.to/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://dev.to/dainyjose/implementing-firebase-crashlytics-in-react-native-12i3</link>
      <guid>https://dev.to/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://dev.to/dainyjose/real-time-location-tracking-live-route-updates-in-react-native-4g15</link>
      <guid>https://dev.to/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://dev.to/dainyjose/showing-nearby-places-routes-in-react-native-maps-34b7</link>
      <guid>https://dev.to/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://dev.to/dainyjose/building-a-location-picker-in-react-native-maps-with-draggable-marker-address-lookup-1d00</link>
      <guid>https://dev.to/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>
  </channel>
</rss>
