From d3bf94799ee6f08a226ca07d72a80a4e1f45e629 Mon Sep 17 00:00:00 2001 From: neodk2004 Date: Sun, 6 Sep 2026 14:07:27 +0200 Subject: [PATCH] fix: exclude mobile/ from the web app's TypeScript checking and Docker build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Next.js's production build type-checks the whole repo by tsconfig.json's default include glob, which picked up mobile/'s .tsx files once the Docker image's git checkout finally included mobile/ (first pull to include it) — none of mobile's own dependencies (react-native, expo-router, ...) are installed in that container, so the build failed outright. mobile/ is now excluded from tsconfig.json and .dockerignore; it's a separate app with its own tsconfig/package.json and was never meant to be type-checked or shipped as part of the web image. Also completes the mobile EAS/FCM push setup (app.json's extra.eas.projectId and googleServicesFile, google-services.json gitignored) and adds a 15s timeout around getExpoPushTokenAsync so a device that can't reach FCM fails visibly instead of hanging silently forever. Co-Authored-By: Claude Sonnet 5 --- .dockerignore | 1 + mobile/.gitignore | 4 ++++ mobile/app.json | 15 +++++++++++++-- mobile/src/hooks/usePushNotifications.ts | 20 +++++++++++++++++--- tsconfig.json | 2 +- 5 files changed, 36 insertions(+), 6 deletions(-) diff --git a/.dockerignore b/.dockerignore index 638b55d..cffdbb4 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,5 +1,6 @@ node_modules scaffold-tmp +mobile .next .git .gitignore diff --git a/mobile/.gitignore b/mobile/.gitignore index 60db44a..4701d6f 100644 --- a/mobile/.gitignore +++ b/mobile/.gitignore @@ -37,6 +37,10 @@ yarn-error.* .env* !.env.example +# Firebase (FCM push credentials) — project-specific, redownload from +# Firebase Console (org.pawfeed.app app) on a fresh clone instead of committing +google-services.json + # typescript *.tsbuildinfo diff --git a/mobile/app.json b/mobile/app.json index d25f4f6..9adbcf0 100644 --- a/mobile/app.json +++ b/mobile/app.json @@ -14,13 +14,17 @@ }, "android": { "package": "org.pawfeed.app", + "googleServicesFile": "./google-services.json", "adaptiveIcon": { "backgroundColor": "#fafafa", "foregroundImage": "./assets/android-icon-foreground.png", "backgroundImage": "./assets/android-icon-background.png", "monochromeImage": "./assets/android-icon-monochrome.png" }, - "predictiveBackGestureEnabled": false + "predictiveBackGestureEnabled": false, + "permissions": [ + "android.permission.RECORD_AUDIO" + ] }, "web": { "favicon": "./assets/favicon.png" @@ -47,6 +51,13 @@ "color": "#f97316" } ] - ] + ], + "extra": { + "router": {}, + "eas": { + "projectId": "e56a076a-08a2-4e4e-afa0-dfc611fba536" + } + }, + "owner": "pawfeed" } } diff --git a/mobile/src/hooks/usePushNotifications.ts b/mobile/src/hooks/usePushNotifications.ts index 4b5541e..98544a8 100644 --- a/mobile/src/hooks/usePushNotifications.ts +++ b/mobile/src/hooks/usePushNotifications.ts @@ -24,14 +24,19 @@ Notifications.setNotificationHandler({ * * Minting a real token needs an EAS project id (app.json's * extra.eas.projectId, set once via `eas init` — a free step, no EAS Build - * required). Until that's set up, this no-ops with a console warning rather + * required) plus FCM credentials (app.json's googleServicesFile) for + * Android. Until both are set up, this no-ops with a console warning rather * than crashing: push delivery is best-effort everywhere else in this stack * (a missing/expired token just means notify.ts silently skips the push). */ export function usePushNotifications(): void { const trpc = useTRPC(); const { isSignedIn } = useAuth(); - const registerMutation = useMutation(trpc.owner.registerPushToken.mutationOptions()); + const registerMutation = useMutation( + trpc.owner.registerPushToken.mutationOptions({ + onError: (err) => console.warn("[push] registerPushToken failed", err), + }) + ); useEffect(() => { if (!isSignedIn || Platform.OS === "web") return; @@ -57,7 +62,16 @@ export function usePushNotifications(): void { } try { - const { data: token } = await Notifications.getExpoPushTokenAsync({ projectId }); + // getExpoPushTokenAsync can hang indefinitely if the device can't + // reach Google's FCM registration backend (seen on some emulators + // without working Play Services network access) — a timeout turns + // that into a visible failure instead of permanent silence. + const { data: token } = await Promise.race([ + Notifications.getExpoPushTokenAsync({ projectId }), + new Promise((_, reject) => + setTimeout(() => reject(new Error("Timed out after 15s")), 15000) + ), + ]); if (!cancelled) registerMutation.mutate({ expoPushToken: token }); } catch (err) { console.warn("[push] Failed to get Expo push token", err); diff --git a/tsconfig.json b/tsconfig.json index cf9c65d..99a302a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -30,5 +30,5 @@ ".next/dev/types/**/*.ts", "**/*.mts" ], - "exclude": ["node_modules"] + "exclude": ["node_modules", "mobile"] }