Quick Start With Supabase
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:
- 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:
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
The .env file should remain secure, as it contains sensitive keys required for the hot-updater to function.
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(),
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 = 0 }) => (
<Modal transparent visible={true}>
<View
style={{
flex: 1,
padding: 20,
borderRadius: 10,
justifyContent: "center",
alignItems: "center",
backgroundColor: "rgba(0, 0, 0, 0.5)",
}}
>
<Text style={{ color: "white", fontSize: 20, fontWeight: "bold" }}>
Updating...
</Text>
<Text style={{ color: "white", fontSize: 20, fontWeight: "bold" }}>
{Math.round(progress * 100)}%
</Text>
</View>
</Modal>
),
})(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>/MainActivity.kt
package com.hotupdaterexample
import android.app.Application
import android.util.Log
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.