You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Firebase新增数据时向所有用户推送通知实现问询

Hey Ahmad, great question! Since you’ve already got FCM configured, let’s walk through exactly how to set up that broadcast notification when a user posts an image. Here’s the step-by-step plan plus code snippets to make it work:

Implementation Roadmap

First, let’s outline the core steps you need to cover:

  • Store every user’s FCM token in your database (so you can target all of them later)
  • Trigger the notification logic right after a successful image upload to your database
  • Fetch all valid FCM tokens from your database
  • Build and send the broadcast notification via Firebase Admin SDK

1. Store User FCM Tokens in Your Database

Before you can send notifications, you need to collect and save each user’s FCM token when they log in. This token is unique per device/user combo.

Client-Side (Android Example)

When a user logs in, fetch their FCM token and save it to your database (I’ll use Firestore here since it’s common with Firebase):

// In your login success handler or MainActivity
FirebaseMessaging.getInstance().token.addOnCompleteListener { task ->
    if (!task.isSuccessful) {
        Log.w("FCM_TOKEN", "Fetching token failed", task.exception)
        return@addOnCompleteListener
    }

    val token = task.result
    // Save token to Firestore, linked to the current user's UID
    FirebaseFirestore.getInstance()
        .collection("users")
        .document(FirebaseAuth.getInstance().currentUser!!.uid)
        .update("fcmToken", token, "isTokenInvalid", false)
        .addOnSuccessListener { Log.d("FCM_TOKEN", "Token saved successfully") }
        .addOnFailureListener { e -> Log.w("FCM_TOKEN", "Failed to save token", e) }
}

2. Trigger Notification on Image Upload

Once your server confirms the image and its details are saved to the database, call the function that sends the broadcast.

Server-Side (Node.js with Firebase Admin SDK)

First, make sure you’ve initialized the Firebase Admin SDK (you should have this set up already):

const admin = require('firebase-admin');
const serviceAccount = require('./your-service-account-key.json');

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: 'https://your-project-id.firebaseio.com'
});

Next, create a function to fetch all valid tokens from your database:

async function getAllValidTokens() {
  try {
    const usersSnapshot = await admin.firestore().collection('users').get();
    const tokens = [];

    usersSnapshot.forEach(doc => {
      const userData = doc.data();
      // Skip tokens that are missing or marked invalid
      if (userData.fcmToken && !userData.isTokenInvalid) {
        tokens.push(userData.fcmToken);
      }
    });

    return tokens;
  } catch (error) {
    console.error('Error fetching tokens:', error);
    return [];
  }
}

Then, build and send the broadcast notification:

async function sendPostNotification(postedByUsername) {
  const tokens = await getAllValidTokens();

  if (tokens.length === 0) {
    console.log('No valid tokens to send notifications to');
    return;
  }

  // Build the notification message
  const message = {
    notification: {
      title: 'New Post Alert!',
      body: `${postedByUsername} Post Something`
    },
    tokens: tokens // Send to all fetched tokens
  };

  try {
    const response = await admin.messaging().sendMulticast(message);
    console.log(`Sent ${response.successCount} notifications successfully`);
    console.log(`Failed to send ${response.failureCount} notifications`);

    // Optional: Mark failed tokens as invalid in the database
    const failedTokens = [];
    response.responses.forEach((resp, index) => {
      if (!resp.success) {
        failedTokens.push(tokens[index]);
      }
    });

    if (failedTokens.length > 0) {
      const batch = admin.firestore().batch();
      // Find each user with a failed token and mark it invalid
      for (const token of failedTokens) {
        const userQuery = await admin.firestore().collection('users')
          .where('fcmToken', '==', token).limit(1).get();
        
        userQuery.forEach(doc => {
          batch.update(doc.ref, { isTokenInvalid: true });
        });
      }
      await batch.commit();
      console.log('Marked invalid tokens in database');
    }
  } catch (error) {
    console.error('Error sending notification:', error);
  }
}

Finally, call this function right after your image upload logic completes:

// Example: After saving image and details to DB
async function handleImageUpload(postedByUsername) {
  // ... your existing code to save image metadata to the database ...

  // Trigger the broadcast notification
  await sendPostNotification(postedByUsername);
}

3. Client-Side Notification Handling

To display the notification on users’ devices, set up a Firebase Messaging Service:

Android Example

Create a service class to handle incoming notifications:

class MyMessagingService : FirebaseMessagingService() {

    override fun onMessageReceived(remoteMessage: RemoteMessage) {
        super.onMessageReceived(remoteMessage)
        
        remoteMessage.notification?.let { notification ->
            showSystemNotification(notification.title, notification.body)
        }
    }

    private fun showSystemNotification(title: String?, body: String?) {
        val intent = Intent(this, MainActivity::class.java).apply {
            flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
        }
        val pendingIntent = PendingIntent.getActivity(
            this, 0, intent, PendingIntent.FLAG_IMMUTABLE
        )

        val channelId = "NEW_POST_CHANNEL"
        val notificationBuilder = NotificationCompat.Builder(this, channelId)
            .setSmallIcon(R.drawable.ic_notification)
            .setContentTitle(title)
            .setContentText(body)
            .setAutoCancel(true)
            .setContentIntent(pendingIntent)
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)

        val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

        // Create notification channel (required for Android 8.0+)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                channelId,
                "New Posts",
                NotificationManager.IMPORTANCE_DEFAULT
            )
            notificationManager.createNotificationChannel(channel)
        }

        notificationManager.notify(0, notificationBuilder.build())
    }
}

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

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

Key Notes to Keep in Mind

  • Token Cleanup: Always handle failed tokens by marking them invalid. This prevents unnecessary API calls and keeps your database clean.
  • Batch Limits: The sendMulticast method supports up to 500 tokens per request. If you have more than 500 users, split the tokens into chunks of 500 and send multiple requests.
  • Customization: You can add extra data to the notification (like the post ID) to let users tap directly to the new image instead of just the main activity.

内容的提问来源于stack exchange,提问作者Ahmad Abbas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:17:40