React Native support is available from modelence v0.19.0.
localStorage and window, you configure the client with configureClient so the SDK knows how to store auth tokens, read device dimensions, and resolve server URLs.
Setup
1
Install dependencies
Add Modelence to your React Native project:You’ll also need
@react-native-async-storage/async-storage (or any other persistent key-value store) to persist the auth token across app restarts.2
Configure the client
Call
configureClient once, before your app mounts — for example at the top of your entry file (App.tsx or index.ts).3
Wrap your app with AppProvider
Load the persisted auth token before mounting your app, then wrap your root component with
AppProvider:ClientConfig reference
Using authentication
Auth functions work the same way as on the web:Calling methods
callMethod works without any changes — it automatically prepends baseUrl to every request:
Live queries and WebSockets
Live queries connect over WebSocket tobaseUrl. No additional configuration is needed beyond configureClient:
OAuth sign-in
Native OAuth sign-in is available from modelence v0.23.0.
1
Allowlist your deep link
The server only redirects to deep links you have explicitly allowed. Set Or as a comma-separated config value, manageable from Modelence Cloud or the environment:Both sources are merged. Until at least one entry exists, mobile sign-in is rejected.
auth.mobile.redirectUrls in startApp:2
Start the flow
Pass the deep link your app listens on.
openUrl must be configured (see Setup above).3
Complete the sign-in
When the flow finishes, Modelence redirects to Handle the cold-start case too. If the app was closed when the deep link
fired, the URL arrives via
myapp://auth?code=.... Exchange that code for a session:Use
parseDeepLinkParams rather than new URL(url).searchParams. React
Native’s built-in URL is a partial implementation that throws on
searchParams; Expo only works because it installs a polyfill.Linking.getInitialURL() and the url event
never runs — so a sign-in that launches the app would silently do nothing:Choosing a redirect URI
redirectUri is where the user should end up once the provider is done —
whatever Linking.createURL('auth') returns for the target you are running on.
Modelence issues a plain HTTP redirect to it, so what happens next depends on the
scheme:
All three are valid. What they share is that each needs its own entry in
auth.mobile.redirectUrls, because the value differs per target.
Two errors follow, and they mean different things:
“This redirectUri is not in auth.mobile.redirectUrls.” The exact string you
passed is not allowlisted. Log the value and add it verbatim — entries match on
scheme, host and path, so a differing port or trailing path is a different
target.
A 404 / “Unmatched Route” page with ?code=… in the URL. The redirect
succeeded and sign-in worked — the code is real — but nothing is serving that
path. On Expo Web this means the /auth route is missing; add it (see the next
section). With a custom scheme it means the app was not installed or the scheme
was not registered.
Expo Web and https:// redirect URIs
Under Expo Web your app is a website, served from an https:// origin, and
Linking.createURL('auth') returns something like
https://your-app.example.com/auth. That is a perfectly good redirect target —
the same React Native code runs unchanged, and Linking.openURL navigates the
current tab.
Two things follow, and both are handled for you:
- The route must exist. Unlike a custom scheme, an
https://redirect is a real page load in your app. Expo Router needs an/authroute, or you get the “Unmatched Route” screen with?code=…in the URL. - The verifier survives the navigation. Leaving the page tears down the
JavaScript context that minted the device-binding verifier, so Modelence
mirrors it into
sessionStoragein browsers and restores it on return. You do not need to do anything; the sameloginWithOAuth({ code })call works.
app/auth.tsx for Expo Router — the same handler as the native case,
reading the code from the page URL:
Each build target needs its own allowlist entry, because
Linking.createURL('auth') returns a different value in each — see the table
below. Add the Expo Web origin alongside your native scheme.Plain web apps (no React Native)
If you are building a plain web app with no native target, skipredirectUri
entirely:
Universal links
Anhttps:// redirect can also be intercepted by the OS and handed to your
native app instead of a browser, via universal
links or Android App Links.
That needs an apple-app-site-association (iOS) or assetlinks.json (Android)
served from the domain plus the matching associated-domain entitlement in the
app. When configured, the URL arrives through the same Linking handler as a
custom scheme and nothing else changes.
A custom scheme (myapp://auth) is simpler if you do not already need universal
links for other reasons.
Expo: one entry per build target
Linking.createURL('auth') returns a different value depending on how the app is
running, and every one of them needs its own allowlist entry:
The Expo Go host follows your LAN address or tunnel, so it cannot be committed to
startApp. That is why auth.mobile.redirectUrls is also readable from the
environment and from Modelence Cloud — set the volatile ones there, per
environment, without a redeploy:
Why a code instead of a token
The deep link carries a single-use code valid for one minute, not the session token. Custom URL schemes can be registered by more than one app on a device, so a token in the redirect could be picked up by an app that isn’t yours. The code is exchanged for the real session over HTTPS inloginWithOAuth, and it cannot be redeemed twice.
The code is also bound to the client that started the flow. signInWithOAuth mints a verifier and loginWithOAuth replays it, so a myapp://auth?code=... link handed to your app from anywhere else is rejected before the code is ever sent.
The verifier is held in memory on native, and additionally mirrored into sessionStorage in browsers so that an Expo Web or plain-browser flow survives the navigation to the provider. It is cleared once redeemed, and when the tab closes. If the app process is killed mid-flow on native, the verifier is gone and the sign-in must be started again.
Linking a provider to an existing account
For an already signed-in user,linkOAuthProvider takes the same redirectUri so the flow returns to your app instead of ending in the browser:
Notes
- No
AppProviderrequired for auth-only usage. You can callloginWithPassword,callMethod, etc. withoutAppProvider. The provider is needed only if you use React hooks likeuseSessionoruseQuery. - Token persistence is your responsibility. Modelence calls
setAuthTokenandgetAuthTokenbut does not bundle a storage library. UseAsyncStorage,expo-secure-store, or any store that fits your security requirements. orientationinClientInfois optional. Passnullif your app does not track orientation.