Zum Inhalt springen
WebViewGold Vibe Coding in den App Store
Deutsch
WebViewGold holen

ChatGPT & Codex

OneSignal-Push-Benachrichtigungen für eine Codex-Web-App mit WebViewGold

Push ist das native Feature, das dem App-Review als Erstes auffällt, und der Großteil der Arbeit steckt in deiner Web-App und deinem Backend. Genau deshalb ist es eine gute Aufgabe für Codex. WebViewGold bringt das OneSignal-SDK in beiden nativen Projekten bereits mit; Codex baut den Opt-in-Moment, synchronisiert die Subscription-ID jedes Geräts mit deinem Server und schreibt den Endpoint, der gezielte Benachrichtigungen verschickt. Hier sind die Aufgabenteilung, die AGENTS.md-Regeln und ein Prompt, der die klassischen Fehler vermeidet.

Ab $109 einmalig pro Plattform, oder unser Team erledigt alles ab $698.

  • Genehmigungsgarantie – oder Geld zurück innerhalb von 14 Tagen
  • Kein Programmieren nötig
  • Einmalzahlung, kostenlose Updates
  • 24/7 Support von echten Menschen
  • Made in Germany seit 2014 · ISO 27001

Das Ziel und was der Reviewer sieht

Das Ziel ist nutzerspezifischer Push: "Neue Antwort auf deinen Kommentar" auf dem Handy einer bestimmten Person, kein Broadcast an alle, die die App installiert haben. Dafür braucht es drei Bausteine: die native App, die bei OneSignal registriert ist, deinen Server, der weiß, welche OneSignal-Subscription zu welchem Nutzer gehört, und einen Sendeaufruf, der beim Tippen auf die Benachrichtigung den richtigen Screen in der App öffnet.

Der Reviewer sieht davon weniger, als du vielleicht denkst, aber er sieht es früh. Ein Berechtigungsdialog, der aufpoppt, bevor der erste Screen überhaupt gerendert ist, wirkt wie eine Website, die sich ohne Grund Berechtigungen holt. Apples Richtlinie 4.5.4 verlangt außerdem, dass die App auch ohne Push funktioniert, und Werbe-Pushes brauchen ein ausdrückliches Opt-in in deiner eigenen UI plus eine Möglichkeit zum Opt-out. Also: nach einer sinnvollen Aktion fragen, erklären, was die Leute bekommen, und einen Schalter in den Einstellungen anbieten. So umgesetzt ist Push eines der deutlichsten Signale für native Funktionalität unter Richtlinie 4.2 (was 4.2 von webbasierten Apps erwartet).

Dieser Guide geht von einem React-Frontend, einer Express-API und Firestore aus, mit dem User-Agent-Helper isNativeApp() aus dem WebViewGold-AGENTS.md-Template. Das Muster lässt sich auf jeden Stack übertragen.

Wer macht was

BausteinWo er liegtWer
OneSignal-App mit Zugangsdaten für APNs (iOS) und FCM (Android)OneSignal-DashboardDu, einmalig
OneSignal in den nativen Apps eingeschaltetiOS: kPushEnabled auf true und oneSignalID in Config.swift. Android: PUSH_ENABLED auf true in Config.java, App-ID in ONE_SIGNAL_APP_ID in build.gradleDu oder Codex im nativen Projekt
Abfrage beim ersten Start ausaskforpushpermissionatfirstrun false (Config.swift), requirePush false (Config.java)Du
Opt-in-Sheet, das den nativen Dialog auslöstWeb-App, Navigation zu registerpush://Codex
Subscription-ID an deinen Servergetonesignalplayerid:// füllt onesignalplayerid; oder schalte autoInjectVariable / AUTO_INJECT_VARIABLES ein; oder empfange ?onesignal_push_id= an der ersten URL über kPushEnhanceUrl / PUSH_ENHANCE_WEBVIEW_URLCodex (Web und Express)
Status in den EinstellungencheckNativePushPermissions:// füllt nativePushEnabled; settingsapp:// öffnet die Systemeinstellungen der AppCodex
VersandExpress ruft die OneSignal-REST-API aufCodex, geprüft von dir

Der AGENTS.md-Abschnitt für Push

Hänge das an deine AGENTS.md an. Codex liest sie zu Beginn jeder Session, und an den Abschnitt mit der Überschrift Review guidelines hält sich das Codex Code Review, wenn du @codex review in einem Pull Request kommentierst. Jedes Schema und jeder Key stammt aus den iOS-Push-Docs und den Android-Push-Docs.

markdown
## Push notifications (OneSignal via WebViewGold)
- Native side: OneSignal is enabled in the WebViewGold projects
  (iOS: kPushEnabled + oneSignalID; Android: PUSH_ENABLED + ONE_SIGNAL_APP_ID).
  The first-run prompt is OFF (askforpushpermissionatfirstrun / requirePush = false).
- Never add the OneSignal Web SDK, a web push service worker or
  Notification.requestPermission(). In the app, permission is requested only by
  navigating to registerpush://, always behind isNativeApp().
- Permission status: checkNativePushPermissions:// sets window.nativePushEnabled
  (asynchronously). If false, offer a button that navigates to settingsapp://.
- Device identity: getonesignalplayerid:// sets window.onesignalplayerid
  (asynchronously; may be empty before the user allows push). Poll with a timeout.
  On iOS, combine data calls: multiapicall://getonesignalplayerid,getappversion
- Storage: pushDevices/{subscriptionId} = { uid, platform, updatedAt }.
  One user can have many devices. Delete the row on logout.
- Sending happens only on the server (server/push/send.js), with ONESIGNAL_API_KEY
  from the environment. Deep links go in data.url (opens inside the app).
  Never set OneSignal's top-level url field: that is the Launch URL and opens the browser.
- Promotional pushes need explicit opt-in in our UI and an opt-out in settings.

## Review guidelines
- P1: ONESIGNAL_API_KEY, or any call to api.onesignal.com, in client code.
- P1: a notification payload with a top-level url instead of data.url.
- P1: registerpush:// or getonesignalplayerid:// without an isNativeApp() check.

WebViewGold hat uns die kürzeste und effizienteste Time-to-Market ermöglicht, die jemals möglich war, verglichen mit allen anderen App-Plattformen, die wir in den letzten 5 Jahren ausprobiert haben. Ich weiß nicht, warum ich euch nicht schon früher entdeckt habe, aber ich bin wirklich, wirklich froh, dass ich es getan habe. Wir nähern uns derzeit fast 6000 App-Downloads im iOS App Store & Google Play Store ohne Probleme!

Antonio Davila · CodeCanyon

Die Codex-Aufgabe

Starte Codex im Repository mit Schreibzugriff auf den Workspace und Freigaben auf Anfrage: codex --sandbox workspace-write --ask-for-approval on-request. In diesem Modus ist das Netzwerk standardmäßig aus, und das passt zu dieser Aufgabe: Sie soll Code und gemockte Tests liefern, keine echten Benachrichtigungen. Ersetze die Teile in eckigen Klammern.

In die Codex CLI oder die IDE-Erweiterung einfügen
Lies zuerst AGENTS.md, besonders die WebViewGold-Bridge und den Push-Abschnitt. Implementiere dann Push-Benachrichtigungen durchgängig in diesem Repository. Fass die nativen Projekte nicht an.

Kontext: Die nativen iOS- und Android-Apps nutzen OneSignal über WebViewGold. Die Berechtigungsabfrage beim ersten Start ist ausgeschaltet (askforpushpermissionatfirstrun = false in Config.swift, requirePush = false in Config.java), also entscheidet unsere Web-App, wann gefragt wird.

1. Opt-in: Nachdem der Nutzer [sein erstes Projekt angelegt hat], zeige ein kurzes Sheet, das erklärt, welche Benachrichtigungen er bekommt ([Antworten, Erinnerungen]), mit "Aktivieren" und "Nicht jetzt". "Aktivieren" navigiert zu registerpush://, wenn isNativeApp() true ist. Merke dir "Nicht jetzt" für 14 Tage. Zeige das Sheet nie im Browser.
2. Subscription-Sync: Navigiere nach dem Login und nach dem Opt-in zu getonesignalplayerid:// und warte auf window.onesignalplayerid (alle 200 ms pollen, nach 5 s aufgeben, leere Werte ignorieren). Sende die ID per POST zusammen mit der Plattform an /api/push/devices, authentifiziert mit dem Firebase-ID-Token. Der Server speichert pushDevices/{subscriptionId} = { uid, platform, updatedAt }, damit ein Handy, das den Besitzer wechselt, zum neuen Nutzer wandert. Rufe beim Logout DELETE /api/push/devices/:id auf, bevor du abmeldest.
3. Einstellungen: eine Zeile "Benachrichtigungen". Navigiere zu checkNativePushPermissions:// und lies window.nativePushEnabled nach einer kurzen Verzögerung. Ist der Wert false, zeige "Benachrichtigungen sind aus" und einen Button, der zu settingsapp:// navigiert.
4. Versand: server/push/send.js exportiert sendPushToUser(uid, { title, body, path }). Die Funktion lädt die pushDevices des Nutzers, ruft die OneSignal-REST-API mit include_subscription_ids auf und legt den Deep Link (unsere Produktions-Origin + path) in data.url ab. Verwende nie das url-Feld auf oberster Ebene. Lies ONESIGNAL_APP_ID und ONESIGNAL_API_KEY aus der Umgebung und trage beide ohne Werte in .env.example ein. Rufe die Funktion aus [dem Handler für neue Antworten] auf.
5. Tests: Unit-Tests für die Geräte-Routen (Auth erforderlich, Upsert, nur eigene Einträge löschen) und für sendPushToUser mit gemocktem fetch. Ruf nicht die echte OneSignal-API auf.
6. Schließe ab mit: geänderten Dateien, Umgebungsvariablen, die ich setzen muss, und einer nummerierten Testliste für echte Geräte.

So sollte die Serverseite aussehen

Nimm das als Maßstab, wenn du das Diff liest. Zwei Zeilen zählen am meisten: Der API-Key verlässt nie den Server, und der Deep Link steht in data.url. OneSignals url auf oberster Ebene ist die Launch URL, die einen Browser öffnet; die WebViewGold-Docs verlangen ausdrücklich stattdessen das Zusatzdatenfeld url.

javascript
// server/push/index.js (Express + firebase-admin, Node 18+ for global fetch)
import express from "express";
import { getFirestore, FieldValue } from "firebase-admin/firestore";
import { requireUser } from "../auth/requireUser.js"; // verifies the Firebase ID token, sets req.uid

const db = getFirestore();
export const pushRouter = express.Router();

// One row per device. The document ID is the OneSignal subscription ID, so a phone
// that changes hands (logout, login as someone else) simply moves to the new user.
pushRouter.post("/api/push/devices", requireUser, express.json(), async (req, res) => {
  const { subscriptionId, platform } = req.body || {};
  if (!subscriptionId) return res.status(400).json({ error: "subscriptionId required" });
  await db.collection("pushDevices").doc(subscriptionId).set({
    uid: req.uid, platform: platform || "unknown", updatedAt: FieldValue.serverTimestamp()
  });
  res.status(204).end();
});

pushRouter.delete("/api/push/devices/:id", requireUser, async (req, res) => {
  const ref = db.collection("pushDevices").doc(req.params.id);
  const snap = await ref.get();
  if (snap.exists && snap.get("uid") === req.uid) await ref.delete();
  res.status(204).end();
});

export async function sendPushToUser(uid, { title, body, path }) {
  const devices = await db.collection("pushDevices").where("uid", "==", uid).get();
  const ids = devices.docs.map((d) => d.id);
  if (ids.length === 0) return 0;

  const res = await fetch("https://api.onesignal.com/notifications?c=push", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: "Key " + process.env.ONESIGNAL_API_KEY // server only
    },
    body: JSON.stringify({
      app_id: process.env.ONESIGNAL_APP_ID,
      target_channel: "push",
      include_subscription_ids: ids,
      headings: { en: title },
      contents: { en: body },
      // WebViewGold opens this inside the app. Not the top-level "url" (Launch URL).
      data: { url: "https://app.example.com" + path }
    })
  });
  if (!res.ok) throw new Error("OneSignal " + res.status + ": " + (await res.text()));
  return ids.length;
}

Von der Config zur ersten Benachrichtigung auf dem Gerät

Plane einen Nachmittag ein; das meiste davon ist Warten auf Builds.

  1. Die OneSignal-App anlegen

    Füge die Plattform Apple iOS mit deinen APNs-Zugangsdaten hinzu und die Plattform Google Android mit dem JSON des Firebase-Dienstkontos, das OneSignal verlangt. Kopiere die App-ID und den App-API-Key. Der Key gehört in die Umgebung deines Servers, niemals in die AGENTS.md, in die Umgebung einer geteilten Cloud-Aufgabe oder ins Client-Bundle.

  2. OneSignal in WebViewGold einschalten

    iOS: kPushEnabled auf true, deine App-ID in oneSignalID, askforpushpermissionatfirstrun auf false und die Capability Push Notifications für deine Bundle-ID aktiviert. Android: PUSH_ENABLED auf true, die App-ID in ONE_SIGNAL_APP_ID in build.gradle, requirePush auf false. Config.swift und Config.java sind reiner Text, also kann eine zweite Codex-Session im WebViewGold-Projekt genau diese Werte setzen; die Signierung bleibt bei dir.

  3. Die Web-Aufgabe ausführen und prüfen

    Füge den Prompt oben ein. Bevor du das Ergebnis übernimmst, tippe /review in der CLI für einen zweiten Durchgang über die nicht committeten Änderungen und lies dann selbst git diff, mit den AGENTS.md-Regeln daneben. Achte zuerst auf die beiden P1-Regeln.

  4. Deployen und die Umgebung setzen

    Setze ONESIGNAL_APP_ID und ONESIGNAL_API_KEY auf dem Server und deploye Web-App und API. Die nativen Projekte ändern sich in diesem Schritt nicht, und genau das ist das Schöne daran, die Logik auf der Web-Seite zu halten.

  5. Für echte Geräte bauen

    TestFlight für iOS, ein interner Test-Track für Android. Push braucht einen signierten Build auf echter Hardware. Kein Mac zur Hand? Der Cloud Builder setzt dieselben WebViewGold-Optionen in einem Browser-Formular und baut beide Apps.

  6. Zweimal senden

    Zuerst aus dem OneSignal-Dashboard mit einem Zusatzdatenfeld url: Das beweist die native Seite. Dann löst du dein eigenes Event aus (eine Antwort, eine Erinnerung): Das beweist den Server, die Gerätezuordnung und den Deep Link.

Checkliste für den Gerätetest

  • Frische Installation: kein Berechtigungsdialog beim Start.
  • Das Opt-in-Sheet erscheint nach der auslösenden Aktion; "Aktivieren" zeigt den nativen Dialog; "Nicht jetzt" wird gemerkt.
  • Nach dem Erlauben ist die Subscription-ID dieses Geräts für den eingeloggten Nutzer gespeichert; ein zweites Gerät legt einen zweiten Eintrag an.
  • Abmelden und auf demselben Handy als anderer Nutzer anmelden: Der Eintrag wandert zum neuen Nutzer, und der alte Nutzer bekommt auf diesem Handy nichts mehr.
  • Berechtigung verweigern, dann die Einstellungen in der App öffnen: Der Status zeigt "aus", und der Button öffnet die Systemeinstellungen über settingsapp://.
  • Auf eine Benachrichtigung tippen, einmal bei geschlossener App und einmal mit der App im Hintergrund: Der Ziel-Screen öffnet sich in der App, nicht in Safari oder Chrome.
  • Android 13 oder neuer: Der Systemdialog erscheint; nativePushEnabled ist nur true, wenn sowohl die Benachrichtigungseinstellung als auch die Laufzeitberechtigung erteilt sind.

Fehler, die Codex ohne die Regeln macht

  • Das OneSignal Web SDK, einen Service Worker oder Notification.requestPermission() hinzufügen. Web-Push ist in der App der falsche Kanal; WebViewGold bringt das native SDK bereits mit.
  • window.onesignalplayerid direkt nach der Navigation auslesen. Injizierte Variablen kommen asynchron an, also mit Timeout pollen.
  • Auf iOS mehrere Bridge-Aufrufe direkt hintereinander abfeuern, wo dann nicht alle ausgeführt werden. Bündle Datenabfragen mit multiapicall://getonesignalplayerid,getappversion (siehe die MultiAPICall-Docs).
  • Eine Push-ID pro Nutzer speichern. Menschen haben ein Handy und ein Tablet; speichere einen Eintrag pro Subscription.
  • Den Deep Link in das url-Feld auf oberster Ebene schreiben, das die Nutzer in den Browser schickt.
  • registerpush:// verdrahten, obwohl in der nativen Config kein Push-Dienst aktiviert ist. Dann passiert nichts, und der Button wirkt kaputt.

Häufig gestellte Fragen

Kann ich statt OneSignal Firebase Cloud Messaging oder Pushwoosh nutzen?

Ja. WebViewGold unterstützt OneSignal, Firebase und Pushwoosh. Für Firebase schaltest du kFirebasePushEnabled (iOS) oder FIREBASE_PUSH_ENABLED (Android) ein, fügst die Google-Service-Dateien hinzu und liest den Token mit getfirebaseplayerid:// aus, das firebaseplayerid füllt. Die AGENTS.md-Regeln bleiben gleich; nur die Variablennamen und die Sende-API ändern sich.

Kann Codex Push-Benachrichtigungen in seiner Sandbox testen?

Nicht durchgängig. Ein Push braucht einen signierten Build auf einem echten Gerät und echte Zugangsdaten. Codex kann die Geräte-Routen und die Sendefunktion mit gemocktem fetch per Unit-Test prüfen, was die meisten Bugs abfängt; der letzte Schritt ist dein Gerätetest.

Warum Subscription-IDs speichern statt OneSignal External IDs zu nutzen?

Weil die WebViewGold-Bridge deiner Web-App die Subscription-ID übergibt (getonesignalplayerid:// oder die injizierte Variable). Das ist also die Kennung, auf die du dich verlassen kannst. Wenn du Subscription-IDs deiner eigenen User-ID zuordnest, bekommst du außerdem Logout, Kontowechsel und Kontolöschung leicht richtig hin.

Soll die Berechtigungsabfrage beim ersten Start eingeschaltet bleiben?

Nur wenn Push von der ersten Sekunde an der Kern der App ist, zum Beispiel bei einer Alarm-App. Bei den meisten Apps sagen mehr Leute Ja, wenn du nach einer sinnvollen Aktion fragst, und es wirkt weniger wie eine Website, die nach Berechtigungen fragt.

Reicht Push, um Richtlinie 4.2 zu bestehen?

Es hilft, aber kein einzelnes Feature garantiert die Freigabe. Reviewer beurteilen das Gesamterlebnis: ein sauberes mobiles Layout, App-typische Navigation, Offline-Verhalten und native Details wie Push und Teilen.

Drei Wege, deine App in die Stores zu bringen

Gleiches Ergebnis, unterschiedlich viel Arbeit auf deiner Seite. Alle drei kommen mit Genehmigungsgarantie und 24/7 Support von echten Menschen.

Selbst machen

$109 pro Plattform, einmalig

Die WebViewGold-Lizenz: ein fertiges Xcode- oder Android-Studio-Projekt. URL einfügen, Name und Icon setzen, Features einschalten, bauen und einreichen. Kostenlose Updates für immer.

Pakete auf der Hauptseite ansehen

Full Service

$698 pro Plattform $798

Schick uns deine URL und dein Icon. Unser Team konfiguriert, baut und liefert deine App innerhalb von 72 Stunden, White-Label, inklusive Quellprojekten. Beide Plattformen für $1,158.

Full-Service-Details Powered by WeSetupYourWebViewApp

Winter-Sale-Preise gültig bis 31. Dezember 2026.

Bereit, deine App zu veröffentlichen?

App Store & Google Play Genehmigungsgarantie – oder Geld zurück innerhalb von 14 Tagen

Lieber abgeben? Full Service: Wir konfigurieren, bauen und liefern innerhalb von 72 Stunden, ab $698 pro Plattform. Fragen? Chatte mit uns – 24/7.

Erstattungen erfolgen zu den in unseren FAQ genannten Bedingungen: eine nicht inhaltsbedingte Ablehnung durch Apple und/oder Google, geltend gemacht innerhalb von 14 Tagen nach dem Kauf.