Fix: Push-Registrierung griff nicht bei bereits eingeloggtem Nutzer
registerDevice lief nur bei Auth-Änderungen (ref.listen) – bestand der Login schon beim App-Start, wurde nie ein FCM-Token gespeichert. Jetzt reaktiv über pushSetupProvider (ref.watch). Zusätzlich: temporäre debugReminders-Function zur Diagnose der Push-Strecke. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
0ce4b2cb19
commit
4bceb8747b
4 changed files with 82 additions and 7 deletions
68
functions/src/debug.ts
Normal file
68
functions/src/debug.ts
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
import {onRequest} from "firebase-functions/v2/https";
|
||||
import * as admin from "firebase-admin";
|
||||
|
||||
/**
|
||||
* TEMPORÄRE Diagnose-Funktion für die Push-Strecke. Wird nach dem Debugging
|
||||
* wieder entfernt. Zugriff nur mit zufälligem Token (kein Erraten möglich);
|
||||
* gibt keine sensiblen Inhalte zurück.
|
||||
*
|
||||
* ?mode=diagnose → Zustand aller Nutzer (Tokens, Zeiten, Slot-Rechnung)
|
||||
* ?mode=send → schickt sofort eine Test-Push an alle Nutzer-Tokens
|
||||
*/
|
||||
const DEBUG_TOKEN = "lftm-dbg-xK92mQ7pW4nT";
|
||||
|
||||
export const debugReminders = onRequest(
|
||||
{region: "europe-west3"},
|
||||
async (req, res) => {
|
||||
if (req.query.token !== DEBUG_TOKEN) {
|
||||
res.status(403).send("forbidden");
|
||||
return;
|
||||
}
|
||||
const db = admin.firestore();
|
||||
const now = new Date();
|
||||
const users = await db.collection("users").get();
|
||||
const report: unknown[] = [];
|
||||
|
||||
for (const userDoc of users.docs) {
|
||||
const user = userDoc.data();
|
||||
const tokens: string[] = user.fcmTokens ?? [];
|
||||
const timezone: string = user.timezone ?? "Europe/Berlin";
|
||||
const reminderTime: string = user.reminderTime ?? "09:00";
|
||||
|
||||
const local = new Intl.DateTimeFormat("en-GB", {
|
||||
timeZone: timezone,
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
hour12: false,
|
||||
}).format(now);
|
||||
|
||||
const entry: Record<string, unknown> = {
|
||||
uid: userDoc.id,
|
||||
tokenCount: tokens.length,
|
||||
tokenPreviews: tokens.map((t) => t.slice(0, 12) + "…"),
|
||||
reminderTime,
|
||||
timezone,
|
||||
localNow: local,
|
||||
householdId: user.householdId ?? null,
|
||||
lastReminderSentOn: user.lastReminderSentOn ?? null,
|
||||
};
|
||||
|
||||
if (req.query.mode === "send" && tokens.length > 0) {
|
||||
const response = await admin.messaging().sendEachForMulticast({
|
||||
tokens,
|
||||
notification: {
|
||||
title: "Test-Push von LeafItToMe 🌱",
|
||||
body: "Wenn du das liest, funktioniert die Push-Strecke.",
|
||||
},
|
||||
apns: {payload: {aps: {sound: "default"}}},
|
||||
android: {notification: {defaultSound: true}, priority: "high"},
|
||||
});
|
||||
entry.sendResults = response.responses.map((r) =>
|
||||
r.success ? "ok" : `${r.error?.code}: ${r.error?.message}`
|
||||
);
|
||||
}
|
||||
report.push(entry);
|
||||
}
|
||||
res.json({now: now.toISOString(), users: report});
|
||||
}
|
||||
);
|
||||
|
|
@ -5,6 +5,7 @@ import * as admin from "firebase-admin";
|
|||
admin.initializeApp();
|
||||
|
||||
export {sendDailyReminders} from "./reminders";
|
||||
export {debugReminders} from "./debug";
|
||||
|
||||
// Secrets liegen im Google Secret Manager (firebase functions:secrets:set),
|
||||
// niemals im Code oder in der App.
|
||||
|
|
|
|||
10
lib/app.dart
10
lib/app.dart
|
|
@ -16,13 +16,9 @@ class LeafItToMeApp extends ConsumerWidget {
|
|||
final settings = ref.watch(settingsProvider);
|
||||
final router = ref.watch(appRouterProvider);
|
||||
|
||||
// Nach jedem Login das Gerät für Push-Erinnerungen registrieren.
|
||||
ref.listen(authStateProvider, (previous, next) {
|
||||
final user = next.value;
|
||||
if (user != null) {
|
||||
ref.read(pushRegistrationServiceProvider).registerDevice(user);
|
||||
}
|
||||
});
|
||||
// Hält die Push-Registrierung aktiv: registriert das Gerät, sobald ein
|
||||
// Nutzer angemeldet ist (auch wenn der Login vor dem App-Start bestand).
|
||||
ref.watch(pushSetupProvider);
|
||||
|
||||
return MaterialApp.router(
|
||||
routerConfig: router,
|
||||
|
|
|
|||
|
|
@ -71,3 +71,13 @@ final pushRegistrationServiceProvider = Provider<PushRegistrationService>((ref)
|
|||
ref.watch(firebaseAuthProvider),
|
||||
);
|
||||
});
|
||||
|
||||
/// Sorgt dafür, dass das Gerät registriert ist, sobald (und solange) ein
|
||||
/// Nutzer angemeldet ist — auch wenn der Login schon vor dem App-Start
|
||||
/// bestand. Wird in app.dart per ref.watch aktiv gehalten.
|
||||
final pushSetupProvider = Provider<void>((ref) {
|
||||
final user = ref.watch(authStateProvider).value;
|
||||
if (user != null) {
|
||||
ref.read(pushRegistrationServiceProvider).registerDevice(user);
|
||||
}
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue