Rakesh Vangari
Rakesh Vangari

Reputation: 17

Issues with Firebase Push Notifications using topics

We have developed an app for short news with over 1L active users across five languages. Users receive push notifications based on their selected language, state, and district. To implement this, we created a Firebase topic for every combination of language, state, and district.

However, we suspect issues with this approach because:

The actual user count for each topic is not as expected. The engagement rate (opens) is significantly lower than anticipated. Here’s the code we’re using for subscribing users to topics and sending notifications. It involves:

Subscribing users to topics in batches of 1,000 registration tokens. Sending a push notification using the Firebase Cloud Messaging (FCM) API.

try {

    let topicName = `${data.language_id}-${pushData.state_id}-${pushData.dist_id}`
    let success = 0
    let failure = 0
    let errors = []

    function pushBatch(registration_ids) {
        return new Promise(async (resolve, reject) => {
            try {
                const pntime = Date.now()
                const response = await admin.messaging().subscribeToTopic(registration_ids, topic);
                console.log("FCM push time", (Date.now() - pntime) / 1000, 'seconds')
                return resolve(response)
            } catch (error) {
                console.error(error)
                return resolve({ successCount: 0, failureCount: 0, errors: [] })
            }
        });
    }

    let pushPromises = []

    for (let index = 0; index < tokens.length; index += 1000) {
        pushPromises.push(pushBatch(tokens.slice(index, index + 1000)))
    }

    let current = Date.now()

    console.log("Executing batch of", pushPromises.length)
    const responses = await Promise.all(pushPromises)

    for (const iterator of responses) {
        success += iterator.successCount
        failure += iterator.failureCount
        errors = [...errors, iterator.errors]
    }

    console.log(`Subscribed to topic ${topic}, success: ${success}, failure: ${failure}`, (Date.now() - current) / 1000, 'seconds')

    const accessToken = await getAccessToken();

    const pushData = {
        message: {
            topic: topic,
            data: {
                post_id: `${data.post_id}`,
                push_id: `${data.push_id}`,
                language_id: `${data.language_id}`,
                category_id: `${data.category_id}`,
                title: `${data.title}`,
                sent_at: `${data.sent_at}`,
                draft_id: `${data.draft_id}`,
                device_id: `${data.device_id}`,
                tag: `${data.tag}`,
                pn_title: `${data.pn_title}`,
                pn_color: `${data.pn_color}`,
                showPNTime: `${data.showPNTime}`,
                image: `${data.image}`
            },
            apns: {
                headers: {
                    "apns-priority": "5"
                },
                payload: {
                    aps: {
                        sound: "buzzer_message",
                        category: "AnyNewsApp"
                    }
                }
            },
            webpush: {
                headers: {
                    Urgency: "high"
                }
            }
        }
    };

    const pushResponse = await axios.request({
        method: 'post',
        maxBodyLength: Infinity,
        url: 'https://fcm.googleapis.com/v1/projects/anynews-2bffa/messages:send',
        headers: {
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${accessToken}`
        },
        data: pushData
    })

    return { success, failure, id: pushResponse.data.name }

} catch (error) {
    console.error("Main PUSH error *****************", error)
}   

Is creating a topic for every language, state, and district combination the right approach, or is there a better alternative for managing such granular segmentation?

Could there be an issue with the way we’re subscribing tokens to topics in batches?

How can we debug or optimize the current implementation to achieve better results?

Upvotes: 0

Views: 25

Answers (0)

Related Questions