Supabase Provider
This guide walks you through setting up hot-updater
with Supabase in a React Native project. You'll configure the environment, install required packages, and initialize Supabase for seamless updates.
Prerequisites
Before you begin, make sure the following are ready:
- Docker Or OrbStack: Install it via Docker or OrbStack.
- Node.js: Version 20 or later is recommended.
- Supabase CLI: Install it via
npx supabase
.
- Supabase Account: Sign up at Supabase if you don’t have one.
Step 1: Install Required Packages
Run the following command to install dependencies:
npm install hot-updater --save-dev
Step 2: Configure Supabase
Run the initialization script to start the interactive setup process. Use the following command with your preferred package manager:
npx -y supabase login
npx hot-updater init
Interactive Setup Steps
- Select a Build Plugin: Choose a build plugin for your project (e.g., Metro for React Native).
- Select a Provider: Select Supabase as the provider for handling updates.
During the setup, you will be prompted to:
- Create or Select a Supabase Organization: Choose an existing organization or create a new one.
- Create or Select a Project: Choose an existing project or create a new one within your organization.
- Configure Storage: Select an existing storage bucket or create a new public bucket to store updates.
- Database Migration: create a new one to store updates.
- Deploy Edge Function: Deploy a Supabase Edge Function called
update-server
.
Once the setup is complete, a .env
file will be generated containing the following keys:
HOT_UPDATER_SUPABASE_ANON_KEY=your-anon-key
HOT_UPDATER_SUPABASE_BUCKET_NAME=your-bucket-name
HOT_UPDATER_SUPABASE_URL=https://your-project-id.supabase.co
WARNING
If you’re not using the react-native-dotenv
solution, the tokens from your .env
file will not be included in your app bundle and are therefore not exposed to risks. However, if you’re still concerned,
please refer to the article below for more details:
Security
Step 3: Generated Configurations
During the initialization process, the following file is automatically generated:
hot-updater.config.ts
: This file contains the configuration settings for integrating Supabase with your project.
hot-updater.config.ts
import { metro } from "@hot-updater/metro";
import { supabaseDatabase, supabaseStorage } from "@hot-updater/supabase";
import { defineConfig } from "hot-updater";
import "dotenv/config";
export default defineConfig({
build: metro({ enableHermes: true }),
storage: supabaseStorage({
supabaseUrl: process.env.HOT_UPDATER_SUPABASE_URL!,
supabaseAnonKey: process.env.HOT_UPDATER_SUPABASE_ANON_KEY!,
bucketName: process.env.HOT_UPDATER_SUPABASE_BUCKET_NAME!,
}),
database: supabaseDatabase({
supabaseUrl: process.env.HOT_UPDATER_SUPABASE_URL!,
supabaseAnonKey: process.env.HOT_UPDATER_SUPABASE_ANON_KEY!,
}),
});
Step 4: Add HotUpdater to Your Project
The HotUpdater component wraps your application, enabling seamless delivery of updates and fallback UI during updates. Follow these steps to integrate it into your App.tsx:
App.tsx
import { HotUpdater } from "@hot-updater/react-native";
function App() {
return (
<View>
<Text>Hello World</Text>
</View>
);
}
export default HotUpdater.wrap({
source: "https://<project-id>.supabase.co/functions/v1/update-server",
requestHeaders: {
// if you want to use the request headers, you can add them here
},
fallbackComponent: ({ progress, status }) => (
<View
style={{
flex: 1,
padding: 20,
borderRadius: 10,
justifyContent: "center",
alignItems: "center",
backgroundColor: "rgba(0, 0, 0, 0.5)",
}}
>
{/* You can put a splash image here. */}
<Text style={{ color: "white", fontSize: 20, fontWeight: "bold" }}>
{status === "UPDATING" ? "Updating..." : "Checking for Update..."}
</Text>
{progress > 0 ? (
<Text style={{ color: "white", fontSize: 20, fontWeight: "bold" }}>
{Math.round(progress * 100)}%
</Text>
) : null}
</View>
),
})(App);
Step 5: Add Babel Plugin to Your Project
In this step, you will configure Babel to set the bundle ID at build time. This is necessary for integrating the hot-updater
plugin into your project.
Add the following to your babel.config.js
file:
babel.config.js
module.exports = {
presets: ['module:@react-native/babel-preset'],
plugins: [
'hot-updater/babel-plugin',
],
};
Step 6: Add Native Code
To complete the integration of hot-updater
, you'll need to add native code modifications for both Android and iOS platforms. This step ensures the hot-updater
can interact with your app's underlying framework to apply updates seamlessly.
Android
android/app/src/main/java/com/<your-app-name>/MainApplication.kt
package com.hotupdaterexample
import android.app.Application
import com.facebook.react.PackageList
import com.facebook.react.ReactApplication
import com.facebook.react.ReactHost
import com.facebook.react.ReactNativeHost
import com.facebook.react.ReactPackage
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
import com.facebook.react.defaults.DefaultReactNativeHost
import com.facebook.react.soloader.OpenSourceMergedSoMapping
import com.facebook.soloader.SoLoader
import com.hotupdater.HotUpdater
class MainApplication : Application(), ReactApplication {
override val reactNativeHost: ReactNativeHost =
object : DefaultReactNativeHost(this) {
override fun getPackages(): List<ReactPackage> =
PackageList(this).packages.apply {
// Packages that cannot be autolinked yet can be added manually here, for example:
// add(MyReactNativePackage())
}
override fun getJSMainModuleName(): String = "index"
override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG
override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
override fun getJSBundleFile(): String? {
return HotUpdater.getJSBundleFile(applicationContext)
}
}
override val reactHost: ReactHost
get() = getDefaultReactHost(applicationContext, reactNativeHost)
override fun onCreate() {
super.onCreate()
SoLoader.init(this, OpenSourceMergedSoMapping)
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
// If you opted-in for the New Architecture, we load the native entry point for this app.
load()
}
}
}
iOS
ios/<your-app-name>/AppDelegate.mm
#import "AppDelegate.h"
#import <HotUpdater/HotUpdater.h>
#import <React/RCTBundleURLProvider.h>
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.moduleName = @"HotUpdaterExample";
// You can add your custom initial props in the dictionary below.
// They will be passed down to the ViewController used by React Native.
self.initialProps = @{};
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
return [self bundleURL];
}
- (NSURL *)bundleURL
{
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
#else
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif
return [HotUpdater bundleURL];
}
@end
Verifying the Setup
- Check your Supabase dashboard for the newly created bucket and edge function.
- Test the HotUpdater integration in your React Native app.
You’re all set! 🎉 Start using hot-updater with Supabase for seamless updates in your React Native app.
This document simplifies the initialization process, making it easy for developers to get started with minimal friction.