@familyctx/supabase
v0.1.4
Published
Supabase adapter for FamilyCtx.
Readme
@familyctx/supabase
Supabase adapter for FamilyCtx with real-time sync, parent authentication, and profile management.
Installation
npm install @familyctx/supabase @familyctx/core @familyctx/react @supabase/supabase-jsDatabase Setup
Run the SQL schema in your Supabase project:
# Copy schema.sql to your Supabase project
# Run it in the SQL EditorThe schema creates:
accountstable (stores parent PIN hash and biometric settings)profilestable (stores parent and child profiles)- RLS policies (ensures users can only access their own data)
- Realtime subscriptions (syncs profile changes across devices)
Usage
1. Wrap Your App
import { createClient } from "@supabase/supabase-js";
import { SupabaseSyncProvider } from "@familyctx/supabase";
import { FamilyCtxProvider } from "@familyctx/react"; // or @familyctx/expo
const supabase = createClient(
"https://your-project.supabase.co",
"your-anon-key"
);
function App() {
return (
<SupabaseSyncProvider supabase={supabase}>
<FamilyCtxProvider>
<YourApp />
</FamilyCtxProvider>
</SupabaseSyncProvider>
);
}2. Authentication
import { useSupabaseAuth, useParentAuth } from "@familyctx/supabase";
function LoginScreen() {
const { login, signUp, loading } = useSupabaseAuth();
const handleLogin = async () => {
const result = await login({
email: "[email protected]",
password: "password123",
});
if (result.success) {
// Logged in! Account and profiles will auto-sync
}
};
const handleSignUp = async () => {
const result = await signUp({
email: "[email protected]",
password: "password123",
parentPin: "1234", // 4-digit PIN for parent mode
});
if (result.success) {
// Account created!
}
};
return (
<View>
<Button onPress={handleLogin}>Login</Button>
<Button onPress={handleSignUp}>Sign Up</Button>
</View>
);
}3. Auto-Sync with Realtime
import { useSupabaseSync } from "@familyctx/supabase";
function Dashboard() {
const { loading, error, synced } = useSupabaseSync();
if (loading) return <Text>Syncing...</Text>;
if (error) return <Text>Error: {error.message}</Text>;
return <YourApp />; // Profiles are synced and will update in real-time
}4. Parent PIN Verification
import { useParentAuth } from "@familyctx/supabase";
import { useActions } from "@familyctx/react";
function ParentPinScreen({ onClose }) {
const { verifyParentPin, loading } = useParentAuth();
const { session } = useActions();
const [pin, setPin] = useState("");
const handleSubmit = async () => {
const result = await verifyParentPin(pin);
if (result.success) {
session.confirmParentMode(); // Enable parent mode
onClose();
} else {
alert(result.error); // "Incorrect PIN"
}
};
return (
<View>
<TextInput value={pin} onChangeText={setPin} secureTextEntry />
<Button onPress={handleSubmit}>Verify</Button>
</View>
);
}5. Manual Profile Saves
import { useSupabaseMutations } from "@familyctx/supabase";
import { useActions } from "@familyctx/react";
function AddProfileScreen() {
const { saveProfile, loading } = useSupabaseMutations();
const { profile } = useActions();
const handleSave = async () => {
const newProfile = {
id: uuid(),
accountId: "account-id",
role: "child",
name: "Emma",
createdAt: Date.now(),
};
// Add to local store
profile.add(newProfile);
// Save to Supabase (syncs to other devices via realtime)
const result = await saveProfile(newProfile);
if (result.success) {
console.log("Profile saved!");
}
};
return <Button onPress={handleSave}>Add Child Profile</Button>;
}6. Biometric Settings
import { useBiometricSettings } from "@familyctx/supabase";
function SettingsScreen() {
const { settings, setBiometricEnabled, loadSettings } = useBiometricSettings();
useEffect(() => {
loadSettings();
}, []);
const handleToggle = async () => {
const result = await setBiometricEnabled(!settings.enabled);
if (result.success) {
console.log("Biometric settings updated!");
}
};
return (
<Switch
value={settings.enabled}
onValueChange={handleToggle}
/>
);
}API Reference
Hooks
useSupabaseAuth()
Handles email/password authentication.
login({ email, password })- Sign insignUp({ email, password, parentPin })- Create accountlogout()- Sign outloading- Auth loading stateerror- Auth error
useParentAuth()
Handles parent PIN verification.
verifyParentPin(pin)- Verify PIN against DB hashsetParentPin(newPin)- Update parent PINloading- Verification loading state
useSupabaseSync()
Auto-syncs account and profiles on mount + realtime updates.
loading- Initial sync loading stateerror- Sync errorsynced- True when initial sync complete
useSupabaseMutations()
Manual save operations.
saveProfile(profile)- Insert/update profiledeleteProfile(profileId)- Delete profileupdateBiometricEnabled(enabled)- Toggle biometric settingloading- Mutation loading state
useBiometricSettings()
Manage biometric preferences.
settings-{ enabled, available }loadSettings()- Fetch from DBsetBiometricEnabled(enabled)- Update preferenceloading- Loading state
Real-time Sync
Profile changes automatically sync across all logged-in devices:
- Device A adds a profile → saves to Supabase
- Supabase broadcasts change via realtime
- Device B receives update → local store updates automatically
No manual refresh needed!
Security
- RLS policies ensure users can only access their own data
- Parent PIN is hashed with bcrypt (never stored in plaintext)
- Biometric preference stored per account
License
MIT
