Skip to content
Flows
App Builder Generated Intermediate · 2-3 hours

Add Push Notifications to Existing App

Integrate Firebase Cloud Messaging so users receive real push notifications and tokens are persisted in the backend.

Start Route · 7 steps

The route

7 steps to Done

  1. 01

    Create Firebase Project & Obtain Credentials

    Provide the cloud messaging service and keys needed for both client and server.

    Preview prompt + verify gate ▾

    1. Log in to Firebase console and create a new project named after the existing app. 2. In the project settings, add an Android app (package ID from the React Native app) and download the generated google-services.json file. 3. Copy the web app config (apiKey, authDomain, projectId, storageBucket, messagingSenderId, appId) into a JSON snippet. 4. In Cloud Messaging settings, locate the Server key (legacy) and the Sender ID. 5. Return a JSON object containing: { "googleServicesFile": "<base64‑encoded google-services.json>", "firebaseConfig": {…}, "serverKey": "<FCM Server Key>", "senderId": "<Messaging Sender ID>" } No placeholders; include real base64 content and keys.

    • Credentials JSON includes googleServicesFile, firebaseConfig, serverKey, and senderId.
    • Values are non‑empty and look like real keys (e.g., serverKey starts with AAA...).
    • Base64 string decodes to a valid google‑services.json.
  2. 02

    Add FCM Client Library and Configure Android Build

    Install the messaging SDK and integrate the downloaded google‑services.json into the React Native project.

    Preview prompt + verify gate ▾

    1. Run `npm install @react-native-firebase/app @react-native-firebase/messaging`. 2. Decode the base64 google‑services.json from step 1 and place it at android/app/google-services.json. 3. In android/build.gradle, add `classpath 'com.google.gms:google-services:4.4.0'` inside the dependencies block. 4. In android/app/build.gradle, apply the plugin at the bottom: `apply plugin: 'com.google.gms.google-services'`. 5. Ensure `minSdkVersion` is >= 21. 6. Commit these changes to the repo. 7. Return a brief summary of the file modifications with line numbers where changes were made. No placeholder code; the file paths must be exact.

    • google‑services.json is present at android/app/
    • Both build.gradle files contain the new lines as described.
    • npm packages appear in package.json with concrete version numbers.
  3. 03

    Implement Permission Request & Token Retrieval on Device

    Obtain the device’s FCM token and request user permission, then send the token to the backend for persistence.

    Preview prompt + verify gate ▾

    Create a new file src/services/pushService.js containing: 1. An async function requestPermission() that calls messaging().requestPermission() and returns true/false. 2. An async function getToken() that calls messaging().getToken() and returns the token string. 3. An async function registerToken(userId) that: a. Calls requestPermission(); if denied, log and exit. b. Calls getToken(); if null, log error. c. Retrieves the auth token from AsyncStorage key 'authToken'. d. Sends a POST to `${BASE_URL}/api/register-token` with headers Authorization: `Bearer ${authToken}` and JSON body {userId, token}. 4. Export registerToken. Add a call to registerToken(currentUser.id) inside the root component’s useEffect (once on mount). Return the complete file content and indicate where you added the useEffect call. No placeholder URLs; use the actual BASE_URL variable already defined in the project.

    • Permission dialog appears on first run.
    • Console logs show a valid token string.
    • Network tab shows a POST to /api/register-token with correct JSON.
  4. 04

    Create Backend Endpoint to Persist Tokens

    Store each user's FCM token in PostgreSQL so notifications can be targeted later.

    Preview prompt + verify gate ▾

    1. Create a new migration (SQL) to add a table `device_tokens` with columns: id SERIAL PRIMARY KEY, user_id INTEGER REFERENCES users(id) ON DELETE CASCADE, token VARCHAR NOT NULL UNIQUE, created_at TIMESTAMP DEFAULT NOW(). 2. In the Express app, add a route: ```js router.post('/api/register-token', authMiddleware, async (req, res) => { const { userId, token } = req.body; if (parseInt(userId) !== req.user.id) return res.status(403).json({error:'User mismatch'}); await db.query('INSERT INTO device_tokens (user_id, token) VALUES ($1, $2) ON CONFLICT (token) DO UPDATE SET user_id = $1', [userId, token]); res.json({status:'ok'}); }); ``` 3. Export the route and ensure it's mounted. 4. Return the SQL migration content and the route code snippet. No placeholders; use actual table/column names.

    • device_tokens table present with id, user_id, token, created_at.
    • POST /api/register-token returns {status:'ok'} for valid auth.
    • Invalid userId triggers 403 response.
  5. 05

    Build Server‑Side Push Sender Service

    Provide an endpoint that triggers an FCM push to a specific user’s devices.

    Preview prompt + verify gate ▾

    1. In `src/routes/notifications.js`, add a new route: ```js router.post('/api/send-notification', authMiddleware, async (req, res) => { const { userId, title, body } = req.body; const tokensResult = await db.query('SELECT token FROM device_tokens WHERE user_id = $1', [userId]); const tokens = tokensResult.rows.map(r => r.token); if (!tokens.length) return res.status(404).json({error:'No device tokens'}); const message = { notification: { title, body }, registration_ids: tokens }; const fcmResponse = await fetch('https://fcm.googleapis.com/fcm/send', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `key=${process.env.FCM_SERVER_KEY}` }, body: JSON.stringify(message) }); const result = await fcmResponse.json(); res.json(result); }); ``` 2. Ensure `process.env.FCM_SERVER_KEY` is set (use dotenv). 3. Return the full route code snippet. No dummy URLs; the fetch must target the real FCM endpoint.

    • POST /api/send-notification returns FCM response JSON.
    • Devices receive a notification with the given title and body.
    • Non‑admin requests are rejected with 403.
  6. 06

    Add In‑App Test Notification UI

    Provide a simple screen for admins to send a test push and verify end‑to‑end flow.

    Preview prompt + verify gate ▾

    1. Add a new file `src/screens/AdminPushScreen.js` containing a functional component with: - Two TextInput fields bound to state variables `title` and `body`. - A Button labeled "Send Test". - On press, call `fetch(`${BASE_URL}/api/send-notification`, { method:'POST', headers:{ 'Content-Type':'application/json', 'Authorization': `Bearer ${authToken}` }, body: JSON.stringify({ userId: currentUser.id, title, body }) })`. - Display a toast or Alert with the response JSON or error. 2. Register this screen in the navigation (e.g., `AdminStackNavigator`). 3. Add a menu item "Test Push" in the admin drawer that navigates to AdminPushScreen. 4. Return the full component code and the navigation addition diff. No placeholder strings; use actual variable names from the project (e.g., `BASE_URL`, `authToken`).

    • Admin screen appears in the drawer.
    • Entering title/body and pressing Send results in a network request.
    • Device shows the notification matching the entered title/body.
  7. 07

    Validate End‑to‑End Delivery

    Confirm that a token is stored, the send endpoint works, and the device receives the push.

    Preview prompt + verify gate ▾

    1. Launch the app on a physical Android device. 2. On first launch, accept the permission prompt. 3. Verify in the backend database that a row exists in `device_tokens` for your user ID. 4. Open the admin drawer, select "Test Push", enter "Test Title" and "Hello World", press Send. 5. Observe the device’s notification shade: a notification with title "Test Title" and body "Hello World" should appear. 6. Capture screenshots of the permission dialog, DB row (e.g., via psql query), and the received notification. 7. Return a short report confirming each step succeeded. No placeholders; include the actual SQL query used.

    • device_tokens table contains the test device token.
    • Admin UI reports a successful FCM response.
    • Device shows the notification with exact title/body.