React Native Examples ​
Complete examples for using Flowfull Clients with React Native (Expo) applications.
Architecture
@pubflow/react-native- For authentication with Flowless (managed auth service)@pubflow/flowfull-client- For HTTP requests to your custom Flowfull backend
Installation ​
bash
# Install both packages
npm install @pubflow/react-native @pubflow/flowfull-client
# Install required peer dependencies
npx expo install @react-native-async-storage/async-storageBasic Setup ​
1. Configure PubflowProvider ​
typescript
// App.tsx
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { PubflowProvider } from '@pubflow/react-native';
import LoginScreen from './src/screens/LoginScreen';
import DashboardScreen from './src/screens/DashboardScreen';
import UsersScreen from './src/screens/UsersScreen';
const Stack = createNativeStackNavigator();
export default function App() {
return (
<PubflowProvider
config={{
baseUrl: process.env.EXPO_PUBLIC_FLOWLESS_URL || 'https://your-flowless.pubflow.com',
bridgeBasePath: '/bridge',
authBasePath: '/auth'
}}
showSessionAlerts={true}
>
<NavigationContainer>
<Stack.Navigator initialRouteName="Login">
<Stack.Screen name="Login" component={LoginScreen} options={{ headerShown: false }} />
<Stack.Screen name="Dashboard" component={DashboardScreen} />
<Stack.Screen name="Users" component={UsersScreen} />
</Stack.Navigator>
</NavigationContainer>
</PubflowProvider>
);
}2. Create Flowfull API Client ​
typescript
// src/api/flowfull.ts
import { createFlowfull } from '@pubflow/flowfull-client';
// Create client for your custom backend
export const flowfull = createFlowfull(
process.env.EXPO_PUBLIC_BACKEND_URL || 'https://api.myapp.com',
{
headers: {
'X-Client-Version': '1.0.0',
'X-Platform': 'mobile'
},
retryAttempts: 3,
timeout: 30000
}
);Authentication with Flowless ​
Login Screen ​
typescript
// src/screens/LoginScreen.tsx
import { useState } from 'react';
import { View, TextInput, Button, Text, StyleSheet, Alert, ActivityIndicator } from 'react-native';
import { useAuth } from '@pubflow/react-native';
export default function LoginScreen({ navigation }: any) {
const { login, isLoading } = useAuth();
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
async function handleLogin() {
if (!email || !password) {
Alert.alert('Error', 'Please fill in all fields');
return;
}
try {
const result = await login({ email: email.toLowerCase(), password });
if (result.success) {
navigation.replace('Dashboard');
} else {
Alert.alert('Error', result.error || 'Login failed');
}
} catch (error: any) {
Alert.alert('Error', error.message || 'An error occurred');
}
}
return (
<View style={styles.container}>
<Text style={styles.title}>Login</Text>
<TextInput
style={styles.input}
placeholder="Email"
value={email}
onChangeText={setEmail}
autoCapitalize="none"
keyboardType="email-address"
/>
<TextInput
style={styles.input}
placeholder="Password"
value={password}
onChangeText={setPassword}
secureTextEntry
/>
{isLoading ? (
<ActivityIndicator size="large" color="#0000ff" />
) : (
<Button title="Login" onPress={handleLogin} />
)}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
padding: 20,
},
title: {
fontSize: 24,
fontWeight: 'bold',
marginBottom: 20,
textAlign: 'center',
},
input: {
borderWidth: 1,
borderColor: '#ddd',
padding: 10,
marginBottom: 10,
borderRadius: 5,
},
});Dashboard Screen ​
typescript
// src/screens/DashboardScreen.tsx
import { View, Text, Button, StyleSheet, ActivityIndicator } from 'react-native';
import { useAuth } from '@pubflow/react-native';
export default function DashboardScreen({ navigation }: any) {
const { user, isAuthenticated, logout, isLoading } = useAuth();
async function handleLogout() {
await logout();
navigation.replace('Login');
}
if (isLoading) {
return (
<View style={styles.container}>
<ActivityIndicator size="large" color="#0000ff" />
</View>
);
}
if (!isAuthenticated) {
navigation.replace('Login');
return null;
}
return (
<View style={styles.container}>
<Text style={styles.title}>Dashboard</Text>
<View style={styles.userInfo}>
<Text><Text style={styles.label}>Name:</Text> {user?.name}</Text>
<Text><Text style={styles.label}>Email:</Text> {user?.email}</Text>
<Text><Text style={styles.label}>User Type:</Text> {user?.userType}</Text>
</View>
<Button title="Logout" onPress={handleLogout} />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
},
title: {
fontSize: 24,
fontWeight: 'bold',
marginBottom: 20,
},
userInfo: {
marginBottom: 20,
},
label: {
fontWeight: 'bold',
},
});Data Fetching from Custom Backend ​
Use @pubflow/flowfull-client to fetch data from your custom Flowfull backend:
User List Screen ​
typescript
// src/screens/UsersScreen.tsx
import { useState, useEffect } from 'react';
import { View, Text, FlatList, StyleSheet, ActivityIndicator } from 'react-native';
import { flowfull } from '../api/flowfull';
interface User {
id: string;
name: string;
email: string;
role: string;
}
export default function UsersScreen() {
const [users, setUsers] = useState<User[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState('');
useEffect(() => {
fetchUsers();
}, []);
async function fetchUsers() {
try {
const data = await flowfull.get<User[]>('/users');
setUsers(data);
} catch (err: any) {
setError(err.message || 'Failed to fetch users');
} finally {
setLoading(false);
}
}
if (loading) {
return (
<View style={styles.center}>
<ActivityIndicator size="large" color="#0000ff" />
</View>
);
}
if (error) {
return (
<View style={styles.center}>
<Text style={styles.error}>{error}</Text>
</View>
);
}
return (
<View style={styles.container}>
<FlatList
data={users}
keyExtractor={(item) => item.id}
renderItem={({ item }) => (
<View style={styles.userItem}>
<Text style={styles.userName}>{item.name}</Text>
<Text style={styles.userEmail}>{item.email}</Text>
<Text style={styles.userRole}>{item.role}</Text>
</View>
)}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
},
center: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
error: {
color: 'red',
fontSize: 16,
},
userItem: {
padding: 15,
borderBottomWidth: 1,
borderBottomColor: '#ddd',
},
userName: {
fontSize: 18,
fontWeight: 'bold',
},
userEmail: {
fontSize: 14,
color: '#666',
},
userRole: {
fontSize: 12,
color: '#999',
marginTop: 5,
},
});Next Steps ​
- React Native Package - Full API reference
- Authentication Guide - Learn more about authentication
- Making API Calls - Advanced API patterns