The field companion lists today's site visits after hosted sign-in returns through a deep link. The session token stays in secure storage.
Clone starters/expo. SDK reference: React Native / Expo.
The job list answers who the technician is on the device. Client state is UX, not a security boundary. Your API must validate the bearer. Apply authorization there.
What you need
| Requirement | Detail |
|---|---|
| Public key | pk_... from the console |
| Environment | Copy .env.example to .env and set EXPO_PUBLIC_PK_AUTHDOG |
| Secret key | Never put sk_... in the app |
| Callback | Register the deep-link callback. Local default: authdog-authn://callback |
Run
npm install
npx expo startOpen the project in Expo Go or a simulator. Tap Sign in, finish the hosted Account portal, and return through the deep link. You should see job_18 (Pier 4, replace meter) and job_19 (Warehouse B, calibrate sensor).
Jobs
handleRedirect stores ?token= after a structure check only. fetchUser() validates it through userinfo. The visits render only after that call. This example uses expo-secure-store. Do not ship the in-memory fallback.
// App.tsx
import { useEffect } from "react"
import { Button, Linking, Text } from "react-native"
import * as SecureStore from "expo-secure-store"
import {
AuthdogProvider,
createSecureStoreAdapter,
useRedirectHandler,
useSignIn,
useUser,
} from "@authdog/react-native"
const publicKey = process.env.EXPO_PUBLIC_PK_AUTHDOG ?? ""
function Home() {
const { signIn } = useSignIn()
const { handleRedirect } = useRedirectHandler()
const { fetchUser, isAuthenticated } = useUser()
const redirectUrl = "authdog-authn://callback"
useEffect(() => {
Linking.getInitialURL().then((url) => {
if (url) handleRedirect(url)
})
const sub = Linking.addEventListener("url", ({ url }) => handleRedirect(url))
return () => sub.remove()
}, [handleRedirect])
useEffect(() => {
if (isAuthenticated) fetchUser()
}, [isAuthenticated, fetchUser])
if (!isAuthenticated) {
return <Button title="Sign in" onPress={() => signIn(redirectUrl)} />
}
return (
<>
<Text>job_18 · Pier 4 · Replace meter · 08:00–10:00</Text>
<Text>job_19 · Warehouse B · Calibrate sensor · 11:30–12:00</Text>
</>
)
}
export default function App() {
return (
<AuthdogProvider
publicKey={publicKey}
storage={createSecureStoreAdapter(SecureStore)}
>
<Home />
</AuthdogProvider>
)
}