Firebase云消息传递:如何在C ++(iOS)的OnMessage中接听电话?

时间:2019-01-12 14:16:31

标签: c++ ios firebase firebase-cloud-messaging

我有一个Wordpress服务器,该服务器使用Firebase Cloud Messaging将消息发送到iOS应用程序(当前不包括通知,仅包含自定义数据的消息)。该消息是使用服务器端的Google's PHP API发送的。发送消息会产生一个200响应代码,其正文为{"name": "projects/myapp/messages/864693047260522177"},因此在我看来发送已顺利完成(如果我发送了错误的JSON数据,则会得到一个400响应代码)。

在iOS应用中,我使用C++ client code接收消息。我已经设置了所有依赖项,并在应用程序启动时调用MessagingListener::OnTokenReceived()之后调用了firebase::messaging::Initialize()函数。对我来说这很好。

但是,问题是,MessagingListener::OnMessage()从未被调用,无论是我自己(从服务器)发送消息时,还是,也没有从Firebase控制台发送测试消息时,都不会调用。要使这项工作有效,我可能会缺少什么?

更新:我突然收到了Firebase Console发送的测试消息。这封邮件是几个小时前发送的,突然间突然弹出。我还没有收到自己的邮件。

注意:

  • 我还在iOS应用程序中使用了C ++中的Google Analytics(分析),它似乎可以正常工作。
  • 认为我已经在iOS应用程序中设置了所有正确的东西,但是我想我可能会错过一些东西(配置文件,启用推送通知等)。
  • 在收到令牌后,通过调用firebase::messaging::Subscribe("mm_actions"),应用程序已订阅我发送的主题。
  • 我在日志输出中看到,订阅C ++中的主题mm_actions在幕后被更改为/topics/mm_actions。此后打印成功。在服务器上,我不允许发送"topic": "/topics/mm_actions",但可以正常发送"mm_actions"
  • C ++ Firebase SDK版本为5.4.3
  • Xcode / Swift版本为10.1 / 4.0
  • 我已经创建了一个配置文件,该配置文件启用了推送通知,已下载并双击它,因此应进行安装。我在Xcode的任何地方都找不到它,所以我不知道它是否实际使用。
  • 获取Oauth2令牌时,我的身份验证范围是https://www.googleapis.com/auth/firebase.messaging
  • 我将邮件发布到https://fcm.googleapis.com/v1/projects/myappid/messages:send

C ++客户端代码(iOS)

Firebase.h

namespace messaging
{
    struct MessagingListener : public firebase::messaging::Listener
    {
        ~MessagingListener() override;
        void OnMessage(const firebase::messaging::Message& message) override;
        void OnTokenReceived(const char* token) override;
    };

    extern MessagingListener gMessagingListener;
    void initialize();
}

Firebase.cpp

namespace messaging
{
    MessagingListener gMessagingListener;

    MessagingListener::~MessagingListener()
    {}

    // This function is never called for mye own messages and test messages
    // from the Firebase Console takes several hours to arrive.
    void MessagingListener::OnMessage(const firebase::messaging::Message& message)
    {
        fprintf(stdout, "From: %s", message.from.c_str());
        fprintf(stdout, "Message ID: %s", message.message_id.c_str());
        fprintf(stdout, "Message type: %s", message.message_type.c_str());
        for (const auto& d : message.data)
        {
            std::string key = d.first;
            std::string val = d.second;
        }
    }

    // Always called after initialize() below
    void MessagingListener::OnTokenReceived(const char* token)
    {
        firebase::messaging::Subscribe("mm_actions");
    }

    // Called on application startup. Everything works fine.
    void initialize()
    {
        firebase::App* app = app::getInstance();
        assert(app);
        if (app)
        {
            firebase::InitResult result = firebase::messaging::Initialize(*app, &gMessagingListener);
            assert(result == firebase::InitResult::kInitResultSuccess);
        }
    }
}

iOS App中的FCM日志输出

2019-01-12 14:50:12.585965+0100 myapp[450:208682] 5.14.0 - [Firebase/Messaging][I-FCM002000] FIRMessaging library version 3.2.2
2019-01-12 14:50:12.608186+0100 myapp[450:208682] 5.14.0 - [Firebase/Messaging][I-FCM001000] FIRMessaging Remote Notifications proxy enabled, will swizzle remote notification receiver handlers. If you'd prefer to manually integrate Firebase Messaging, add "FirebaseAppDelegateProxyEnabled" to your Info.plist, and set it to NO. Follow the instructions at:
https://firebase.google.com/docs/cloud-messaging/ios/client#method_swizzling_in_firebase_messaging
to ensure proper integration.
2019-01-12 14:50:15.713285+0100 myapp[450:208747] 5.14.0 - [Firebase/Messaging][I-FCM002010] The subscription operation is suspended because you don't have a token. The operation will resume once you get an FCM token.
2019-01-12 14:50:19.120085+0100 myapp[450:208641] 5.14.0 - [Firebase/Messaging][I-FCM017000] Topic subscription request: sender=fAKBne8z1Ek:APA91bEV2R36cZXX_a8C0zTgw3zhJVb0hD02QT7Zex2Ou5Sddiq2c8OQIj5cU44hgC6WFB64Go02y-0fjYUYic2nESSLAOrmiBedg-tKSjMyIZuahPDv6N7n6aOs4vIw71sc6eeIibnd&app=com.mycompany.myapp&device=5622054262136970124&app_ver=1.0&X-gcm.topic=/topics/mm_actions&X-scope=/topics/mm_actions
2019-01-12 14:50:19.123922+0100 myapp[450:208641] 5.14.0 - [Firebase/Messaging][I-FCM005000] Start connecting to FIRMessaging service.
2019-01-12 14:50:19.124284+0100 myapp[450:208641] 5.14.0 - [Firebase/Messaging][I-FCM015000] Opening secure socket to FIRMessaging service
2019-01-12 14:50:19.124643+0100 myapp[450:208641] 5.14.0 - [Firebase/Messaging][I-FCM015006] Secure socket to FIRMessaging service opened
2019-01-12 14:50:19.124992+0100 myapp[450:208641] 5.14.0 - [Firebase/Messaging][I-FCM005001] Connected to FIRMessaging service.
2019-01-12 14:50:19.126362+0100 myapp[450:208641] 5.14.0 - [Firebase/Messaging][I-FCM005017] RMQ: Sending GtalkLoginRequest with outgoing stream Id: 1.
2019-01-12 14:50:19.126782+0100 myapp[450:208641] 5.14.0 - [Firebase/Messaging][I-FCM005023] Send msg: (null) type: -2 inStreamId: 0 outStreamId: 1
2019-01-12 14:50:19.127276+0100 myapp[450:208641] 5.14.0 - [Firebase/Messaging][I-FCM005015] RMQ: Receiving GtalkLoginResponse with incoming stream Id: 1.
2019-01-12 14:50:19.127504+0100 myapp[450:208641] 5.14.0 - [Firebase/Messaging][I-FCM005012] Logged onto MCS service.
2019-01-12 14:50:19.128014+0100 myapp[450:208641] 5.14.0 - [Firebase/Messaging][I-FCM005017] RMQ: Sending GtalkHeartbeatPing with outgoing stream Id: 2.
2019-01-12 14:50:19.129285+0100 myapp[450:208641] 5.14.0 - [Firebase/Messaging][I-FCM005023] Send msg: (null) type: 0 inStreamId: 1 outStreamId: 2
2019-01-12 14:50:19.129859+0100 myapp[450:208641] 5.14.0 - [Firebase/Messaging][I-FCM005015] RMQ: Receiving GtalkIqStanza with incoming stream Id: 2.
2019-01-12 14:50:19.130287+0100 myapp[450:208641] 5.14.0 - [Firebase/Messaging][I-FCM005015] RMQ: Receiving GtalkHeartbeatAck with incoming stream Id: 3.
2019-01-12 14:50:19.130584+0100 myapp[450:208641] 5.14.0 - [Firebase/Messaging][I-FCM005019] RMQ: Server last received stream Id: 2.
2019-01-12 14:50:19.158348+0100 myapp[450:208641] 5.14.0 - [Firebase/Messaging][I-FCM004003] Successfully subscribed to topic /topics/mm_actions
2019-01-12 14:50:45.899272+0100 myapp[450:208682] 5.14.0 - [Firebase/Messaging][I-FCM005023] Send msg: (null) type: 0 inStreamId: 3 outStreamId: 3
2019-01-12 14:50:45.900326+0100 myapp[450:208682] 5.14.0 - [Firebase/Messaging][I-FCM005015] RMQ: Receiving GtalkHeartbeatAck with incoming stream Id: 4.
2019-01-12 14:50:45.901406+0100 myapp[450:208682] 5.14.0 - [Firebase/Messaging][I-FCM005019] RMQ: Server last received stream Id: 3.
2019-01-12 14:51:15.115197+0100 myapp[450:208682] 5.14.0 - [Firebase/Messaging][I-FCM005017] RMQ: Sending GtalkHeartbeatPing with outgoing stream Id: 4.
2019-01-12 14:51:15.115707+0100 myapp[450:208682] 5.14.0 - [Firebase/Messaging][I-FCM005023] Send msg: (null) type: 0 inStreamId: 4 outStreamId: 4
2019-01-12 14:51:15.142261+0100 myapp[450:208682] 5.14.0 - [Firebase/Messaging][I-FCM005015] RMQ: Receiving GtalkHeartbeatAck with incoming stream Id: 5.
2019-01-12 14:51:15.146010+0100 myapp[450:208682] 5.14.0 - [Firebase/Messaging][I-FCM005019] RMQ: Server last received stream Id: 4.

PHP服务器代码

由于我收到Google的200响应,因此我在这里省略了PHP代码。如果可以以某种方式提供帮助,我将其粘贴,但是我看不出原因。我的请求标头包含一个Oauth2令牌,我的请求正文如下:

{
    "message": {
        "topic": "mm_actions",
        "data": {
            "action": "sync_db"
        }
    }
}

我使用this documentation来设置JSON请求正文。

1 个答案:

答案 0 :(得分:0)

不能100%确定原因,但是一段时间后它突然开始工作。这是思考发生的事情:

  1. 我在firebase::messaging::Subscribe("mm_actions");中添加了MessagingListener::OnTokenReceived()。我起初没有这样做,所以很可能一开始就是这样。
  2. 从Firebase控制台测试消息,然后开始到达MessagingListener::OnMessage()
  3. 直到我意识到我已经将"validate_only": true放入JSON数据中之后,服务器的消息才通过,从而使这些消息无处不在。删除它使一切正常工作。

所以我学到了以下内容:

  1. 如果设备未订阅您发送的主题,则无法发送数据消息。
  2. 即使用户拒绝了通知,也可以发送数据消息。