ANLEITUNG

Deine erste App mit React Native

Eine To-do-Liste für iPhone und Android, in der sich Leute registrieren und nur ihre eigenen Aufgaben sehen. Sie nutzt Expo und @espobase/client; Datenbank und Schlüssel kommen aus dem Dashboard.

← Alle Anleitungen

1. Projekt und Tabelle anlegen

Lege im Dashboard ein Projekt an. Öffne den SQL-Editor und führe aus:

create table todos (
  id bigint generated by default as identity primary key,
  owner_id uuid not null default espobase.user_id(),
  title text not null,
  done boolean not null default false,
  created_at timestamptz not null default now()
);

-- Row level security is already on. Each signed-in user sees and changes only their own todos:
create policy "Users manage their own todos" on todos
  for all
  using (owner_id = espobase.user_id())
  with check (owner_id = espobase.user_id());

2. Einstellungen und Schlüssel

  • API: Erstelle einen veröffentlichbaren Schlüssel und kopiere ihn jetzt; Schlüssel werden nur beim Erstellen angezeigt. Lege nie einen geheimen Schlüssel (eb_sk_…) in eine App: Jeder kann eine App entpacken und ihn lesen.
  • Authentifizierung › Einstellungen: Trage den Link deiner App unter Erlaubte Weiterleitungs-URLs ein, zum Beispiel myapp://auth/callback, wobei myapp das scheme in deiner app.json ist. Bestätigungs-E-Mails und die Anmeldung über soziale Konten kehren dorthin zurück.

3. Installieren

npm install @espobase/client
npx expo install @react-native-async-storage/async-storage react-native-get-random-values react-native-url-polyfill expo-web-browser expo-linking

React Native fehlen ein paar Dinge, die Browser haben. Zwei kleine Pakete liefern sie nach; importiere sie vor allem anderen:

# .env (Expo reads EXPO_PUBLIC_ variables; the PUBLISHABLE key is safe in an app)
EXPO_PUBLIC_ESPOBASE_URL=https://api.espobase.com/project/<your project ref>
EXPO_PUBLIC_ESPOBASE_KEY=eb_pk_…

4. Der Client

Ein Telefon hat kein localStorage, also gib dem Client einen Ort für die Sitzung. Sie wird für dich erneuert, und die Person bleibt beim Neustart der App angemeldet.

// lib/espobase.ts
import "react-native-get-random-values"; // crypto.getRandomValues
import "react-native-url-polyfill/auto"; // a complete URL class
import AsyncStorage from "@react-native-async-storage/async-storage";
import { createClient } from "@espobase/client";

export const espobase = createClient(
  process.env.EXPO_PUBLIC_ESPOBASE_URL!,
  process.env.EXPO_PUBLIC_ESPOBASE_KEY!,
  { auth: { storage: AsyncStorage } },
);

5. Registrieren und anmelden

import * as Linking from "expo-linking";
import { espobase } from "@/lib/espobase";

// myapp://auth/callback (the scheme comes from app.json). Add it under Authentication › Settings.
const redirectTo = Linking.createURL("auth/callback");

await espobase.auth.signUp({ email, password, options: { redirectTo } });
await espobase.auth.signInWithPassword({ email, password });

// The confirmation email opens the app at redirectTo#type=signup&token=…
Linking.addEventListener("url", async ({ url }) => {
  const token = new URLSearchParams(url.split("#")[1] ?? "").get("token");
  if (token) await espobase.auth.verifyEmail({ token });
});

// Re-render when the user signs in or out.
espobase.auth.onAuthStateChange((_event, session) => setSession(session));

Ist die E-Mail-Bestätigung aktiv, bekommt die Person einen Link, der deine App unter der Adresse öffnet, die du als redirectTo übergeben hast, mit dem Token nach einem #. Bestätige ihn mit espobase.auth.verifyEmail({ token }).

6. Mit Google oder GitHub anmelden

import * as WebBrowser from "expo-web-browser";
import * as Linking from "expo-linking";
import { espobase } from "@/lib/espobase";

export async function signInWithGoogle() {
  const redirectTo = Linking.createURL("auth/callback");
  const { data } = await espobase.auth.signInWithOAuth({
    provider: "google",
    options: { redirectTo, skipBrowserRedirect: true },
  });
  const result = await WebBrowser.openAuthSessionAsync(data!.url, redirectTo);
  if (result.type !== "success") return; // cancelled
  const code = new URL(result.url).searchParams.get("code");
  if (code) await espobase.auth.exchangeCodeForSession(code);
}

Schalte zuerst den Anbieter unter Authentifizierung › Anbieter ein. Die App öffnet den Anbieter im System-Browser und holt die Person über den Link deiner App zurück; exchangeCodeForSession schließt die Anmeldung ab. Nur diese App kann sie abschließen: Das einmalige Geheimnis bleibt auf dem Telefon.

7. Daten lesen und schreiben

import { useEffect, useState } from "react";
import { espobase } from "@/lib/espobase";

export function useTodos() {
  const [todos, setTodos] = useState<{ id: number; title: string; done: boolean }[]>([]);
  useEffect(() => {
    espobase.from("todos").select("*").order("created_at").then(({ data }) => setTodos(data ?? []));
  }, []);
  return todos;
}

// owner_id fills itself in (its default is espobase.user_id()).
await espobase.from("todos").insert({ title: "Buy milk" });

Jede Anfrage trägt die angemeldete Person, und die Datenbank wendet deine Regel an. Wer nicht angemeldet ist, bekommt eine leere Liste, und niemand kann die Aufgaben eines anderen lesen oder ändern, auch nicht durch direkten Aufruf der API.

8. Ein Foto hochladen

Lege unter Storage einen Bucket an und füge eine Richtlinie hinzu, damit jede Person in ihren eigenen Ordner schreiben darf (siehe die Anleitung zu Datei-Uploads). Übergib die Bytes der Datei (ein ArrayBuffer) an upload: Datei-Uploads

import * as ImagePicker from "expo-image-picker";
import { espobase } from "@/lib/espobase";

const picked = await ImagePicker.launchImageLibraryAsync({ mediaTypes: ["images"] });
if (!picked.canceled) {
  const asset = picked.assets[0]!;
  const bytes = await (await fetch(asset.uri)).arrayBuffer();
  const { data: session } = await espobase.auth.getSession();
  const userId = session.session!.user.id;
  await espobase.storage.from("photos").upload(`${userId}/photo.jpg`, bytes, { contentType: "image/jpeg" });
}

Gut zu wissen

  • Nimm für Anmelde-Links einen Development-Build (npx expo run:ios oder run:android) statt Expo Go: Die Adresse von Expo Go ändert sich mit deinem Netzwerk und lässt sich daher nicht einmalig eintragen.
  • Andere React-Native-Setups funktionieren genauso: dieselben Pakete installieren, die beiden Polyfills zuerst importieren und createClient ein Speicherobjekt übergeben.
  • Auch Realtime funktioniert: React Native bringt WebSockets mit, espobase.realtime braucht also nichts extra.