Firebase Cloud Messaging Integration Guide

Prerequisites

  1. A Firebase project linked to your Android application
  2. The Firebase service account credentials (already configured on the server)
  3. Basic knowledge of Android development

Step 1: Add Firebase to Your Android Project

  1. Open your Android Studio project
  2. Go to Tools > Firebase to open the Firebase Assistant
  3. Select "Cloud Messaging" and follow the steps to connect your app to Firebase
  4. Add the required dependencies to your build.gradle file:
    // Add these dependencies to your app/build.gradle file
    implementation platform('com.google.firebase:firebase-bom:32.1.1')
    implementation 'com.google.firebase:firebase-messaging'
    implementation 'com.google.firebase:firebase-analytics'

Step 2: Create a Firebase Messaging Service

Create a new class that extends FirebaseMessagingService:

public class MyFirebaseMessagingService extends FirebaseMessagingService {
    private static final String TAG = "MyFirebaseMsgService";

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        // Handle FCM messages here
        Log.d(TAG, "From: " + remoteMessage.getFrom());

        // Check if message contains a notification payload
        if (remoteMessage.getNotification() != null) {
            String title = remoteMessage.getNotification().getTitle();
            String body = remoteMessage.getNotification().getBody();
            Log.d(TAG, "Message Notification Title: " + title);
            Log.d(TAG, "Message Notification Body: " + body);
            
            sendNotification(title, body, remoteMessage.getData());
        }
        
        // Check if message contains data payload
        if (remoteMessage.getData().size() > 0) {
            Log.d(TAG, "Message data payload: " + remoteMessage.getData());
            // Handle data payload if needed
        }
    }

    @Override
    public void onNewToken(String token) {
        // Send the new token to your server
        Log.d(TAG, "Refreshed token: " + token);
        sendRegistrationToServer(token);
    }

    private void sendRegistrationToServer(String token) {
        // Implement this method to send token to your backend
        // This is where you call the FCM token registration API
    }

    private void sendNotification(String title, String messageBody, Map data) {
        // Create and show the notification using NotificationCompat.Builder
        // Implement based on your app's UI requirements
    }
}

Don't forget to register your service in AndroidManifest.xml:

<service
    android:name=".MyFirebaseMessagingService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

Step 3: Register FCM Token with IdeaForge Connect API

After user login, register the FCM token with our backend using the FCM token registration endpoint:

private void registerFcmToken(String userToken, String fcmToken) {
    // Create JSON request body
    JSONObject requestBody = new JSONObject();
    try {
        requestBody.put("token", fcmToken);
        requestBody.put("device_info", Build.MANUFACTURER + " " + Build.MODEL);
    } catch (JSONException e) {
        e.printStackTrace();
        return;
    }

    // Create request
    Request request = new Request.Builder()
        .url("https://ideaforgeconnect.replit.app/api/fcm/register-token")
        .addHeader("Authorization", "Bearer " + userToken)
        .addHeader("Content-Type", "application/json")
        .post(RequestBody.create(MediaType.parse("application/json"), requestBody.toString()))
        .build();

    // Execute request asynchronously
    OkHttpClient client = new OkHttpClient();
    client.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            Log.e(TAG, "Failed to register FCM token: " + e.getMessage());
        }

        @Override
        public void onResponse(Call call, Response response) throws IOException {
            if (response.isSuccessful()) {
                Log.d(TAG, "FCM token registered successfully");
            } else {
                Log.e(TAG, "Failed to register FCM token: " + response.code() + " " + response.message());
            }
        }
    });
}

You should call this method:

  1. Right after user login
  2. When a new FCM token is generated (in onNewToken() method)
  3. When the app starts, if the user is already logged in

Step 4: Handle Incoming Notifications

Create a notification channel (for Android 8.0 and above) and display notifications when received:

private void createNotificationChannel() {
    // Create the NotificationChannel, but only on API 26+ (Android 8.0)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        String channelId = "default_channel";
        CharSequence name = "Default Channel";
        String description = "Channel for app notifications";
        int importance = NotificationManager.IMPORTANCE_DEFAULT;
        NotificationChannel channel = new NotificationChannel(channelId, name, importance);
        channel.setDescription(description);
        
        // Register the channel with the system
        NotificationManager notificationManager = getSystemService(NotificationManager.class);
        notificationManager.createNotificationChannel(channel);
    }
}

private void showNotification(String title, String body, Map data) {
    String channelId = "default_channel";
    Intent intent = new Intent(this, MainActivity.class);
    
    // Add data from notification to the intent if needed
    if (data != null) {
        for (Map.Entry entry : data.entrySet()) {
            intent.putExtra(entry.getKey(), entry.getValue());
        }
    }
    
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
            PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE);

    Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    NotificationCompat.Builder notificationBuilder =
            new NotificationCompat.Builder(this, channelId)
                    .setSmallIcon(R.drawable.ic_notification)
                    .setContentTitle(title)
                    .setContentText(body)
                    .setAutoCancel(true)
                    .setSound(defaultSoundUri)
                    .setContentIntent(pendingIntent);

    NotificationManager notificationManager =
            (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

    // Generate unique notification ID
    int notificationId = (int) System.currentTimeMillis();
    notificationManager.notify(notificationId, notificationBuilder.build());
}

Step 5: Testing Notifications

You can test your notification implementation using:

  1. The admin panel at /admin/notifications to send notifications
  2. The test API endpoint: /api/fcm/test

To use the test endpoint, make a POST request with valid JWT token:

// Send test notification request
Request request = new Request.Builder()
    .url("https://ideaforgeconnect.replit.app/api/fcm/test")
    .addHeader("Authorization", "Bearer " + userToken)
    .post(RequestBody.create(MediaType.parse("application/json"), "{}"))
    .build();

API Endpoints Reference

Endpoint Method Description Request Body
/api/fcm/register-token POST Register a new FCM token for the current user
{
  "token": "Firebase FCM token",
  "device_info": "Optional device info"
}
/api/fcm/test POST Send a test notification to the current user Empty JSON object: {}
/api/notifications GET Get all notifications for the current user N/A
/api/notifications/mark-read/{id} POST Mark a notification as read N/A
/api/notifications/unread-count GET Get count of unread notifications N/A