如何国际化/本地化您的FCM推送通知,特别是主题?

18

我想使用Firebase向本地化的Android和iOS设备发送推送通知。

我意识到我们没有真正解决向订阅主题发送本地化消息的问题。 假设我有一条信息“朝鲜领导人威胁关岛”,我想将其发送给订阅“新闻”主题的人,有1000人订阅(他们都讲不同的语言)。 我希望Firebase在请求FCM令牌时记录设备的区域设置,并且我可以只向这个主题发送每个区域设置的消息数组,让FCM/Firebase处理,像这样:

{
  "default_message": "North Korea leader threatens Guam",
  "en_US": "North Korea leader threatens Guam",
  "en_GB": "North Korea leader threatens Guam",
  "es_MX": "Líder de Corea del Norte amenaza a Guam",
  "fr_FR": "Le chef de la Corée du Nord menace Guam",
  "de_DE": "Nordkorea-Führer droht Guam"
}
我看到一些参考资料可能使用title_loc_key,body_loc_key,但没有一个好的示例说明请求的格式。这两个参数也暗示着它们只是用作翻译查找键,应用程序也必须在本地存储和查找,我不能向人们发送全新的即兴本地化消息(因为翻译必须事先存储在应用程序中,例如“april_newsletter_text”)。不确定如何工作,只是随便想了一些想法。
注意:我正在使用php库发送firebase推送通知(Laravel-FCM)。我相信我们团队中的一些开发人员还扩展了该库以执行一些自定义任务,因此如果有一种直接通过GCM(gcm-http.googleapis.com/gcm/)而不是FCM进行操作的方式,则可以添加。

注意:这是我在StackOverflow上找到的关于此问题的最多信息,但它并没有真正回答标题中的一般问题(认为它更多地回答了关于“应用程序处于特殊状态时如何本地化”的正文问题):https://stackoverflow.com/questions/37907470/firebase-push-messages-localization - armyofda12mnkeys
1
你是正确的,如果你想使用title_loc_key和其他键,你需要在你的应用程序包中添加本地化内容。请参阅本地化远程通知的内容。FCM不允许开箱即用的自动推送通知本地化。 - nathan
当用户安装应用并注册时,我们知道他们的语言环境。因此,我们在我们的 CMS 中针对消息本地化翻译,并且移动 API(在 CMS 中)可以查找要发送给特定用户的消息的翻译并发送它。我们还使用自己的主题系统(通过链接到我们的主题表),而不是使用 FCM 的主题,因为我们需要结合许多 AND 和 OR 运算(据我所知,FCM 只能进行 2 个操作)。因此,如果您想将消息发送给主题“(Continent=='NorthAmerica' || 'SouthAmerica' && project=='ProjectA' || B)”中的用户,我们会找到该主题中的所有用户然后向他们发送消息。 - armyofda12mnkeys
2
以上方法的缺点是,对于500个用户,需要发送500条FCM消息,而使用FCM主题只需发送1条消息。因为每个用户的翻译都不同,特别是如果我们的消息中有变量,比如“你好${first_name},请点击这里在${todays_date}使用应用程序”(我们还在移动API和CMS中进行变量替换)。 - armyofda12mnkeys
2个回答

2
如果您正在使用Firebase,那么您的JS工作程序中可能会有如下代码。
let messaging = firebase.messaging();
messaging.setBackgroundMessageHandler(function (payload) {
# Here  the callback for web push notification

通常情况下,您会在此回调中显示消息。任务是本地化它。因此,您可以向用户发送有关新消息的消息。获取本地化消息,然后将其显示给用户。在获取时,您将获得Accept-Language HTTP头或您可以发送用户ID。以下是我项目中的示例:
messaging.setBackgroundMessageHandler(function (payload) {

    let data = [];
    try {
        if (payload.data && payload.data.data) {
            data = JSON.parse(payload.data.data);
        }
    } catch (e) {
        Sentry.captureException(e);
    }
    let query = Object.keys(data).map(k => encodeURIComponent(k) + '=' + encodeURIComponent(data[k])).join('&');

    return fetch(self.location.origin + "/web-push/run.json?" + query)
        .then(function (response) {
            # ........................
            #.  Skipped working with https status codes code.
            # ........................
            return response.json();
        })
        .then(function (response) {
            #
            #  Here we have an localised response from the server
            # 
            if (response) {
                return self.registration.showNotification(response.title, {
                    priority: "high",
                    tag: 'renotify',
                    requireInteraction: true,
                    body: response.description,
                    icon: response.icon,
                    image: response.image,
                    url: response.link,
                    click_action: response.link,
                    data: {
                        url: response.link
                    },
                    vibrate: [500, 110, 500, 110, 450, 110, 200, 110, 170, 40, 450, 110, 200, 110, 170, 40, 500]
                })
            }
        })
        .catch(function (err) {
            Sentry.captureException(err);
        });
});

1
您可以使用“条件”(参见文档)组合主题。这使您能够将通知发送到一组主题,例如:
const message = {
    notification: {
        title: 'North Korea leader threatens Guam',
        body: '...'
    },
    condition: `'KoreaNews' in topics && 'LangEnGB' in topics`
};

const messageFr = {
    notification: {
        title: 'Le chef de la Corée du Nord menace Guam',
        body: '...'
    },
    condition: `'KoreaNews' in topics && 'LangFrFR' in topics`
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接