c++ - Firebase 云消息传递 : How to receive calls in OnMessage in C++ (iOS)?

标签 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接收消息。我已经设置了所有依赖项,并且在应用程序启动时调用 firebase::messaging::Initialize() 之后调用了 MessagingListener::OnTokenReceived() 函数。这对我来说似乎很好。

然而,问题是 MessagingListener::OnMessage() 从未被调用,无论是在我自己(从服务器)发送消息时,还是在我发送测试消息时Firebase 控制台。为了完成这项工作,我可能缺少什么?

更新:我突然收到一条来自Firebase Console的测试消息。 .此消息是几个小时前发送的,突然弹出。我还没有收到自己的消息。

注意事项:

  • 我还在 iOS 应用程序中使用 C++ 中的 Google Analytics,它似乎工作正常。
  • 认为我已经在 iOS 应用程序中正确设置了所有内容,但我想我可能遗漏了某些内容(配置文件、启用的推送通知等)。
  • 应用程序在收到 token 后通过调用 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 token 时我的授权范围是 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 应用中的 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 服务器代码

我在这里省略了 PHP 代码,因为我收到了来自 Google 的 200 响应。如果它能以某种方式提供帮助,我会粘贴它,但我不明白为什么。我的请求 header 包含一个 Oauth2 token ,我的请求正文是这样的:

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

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

最佳答案

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

  1. 我在 MessagingListener::OnTokenReceived() 中添加了 firebase::messaging::Subscribe("mm_actions");。起初我没有这样做,所以这很可能是最初缺少的。
  2. 来自 Firebase 控制台的测试消息随后开始传送至 MessagingListener::OnMessage()
  3. 直到我意识到我已将 "validate_only": true 放入我的 JSON 数据中,使消息成为空运行时,我的服务器才发出消息。删除它使一切都按预期工作。

所以我学到了以下内容:

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

关于c++ - Firebase 云消息传递 : How to receive calls in OnMessage in C++ (iOS)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54160414/

相关文章:

ios - "hide"具有自动布局的 subview 的 UIView

swift - 在展开可选值时意外发现 nil(firebase,swift)

c++ - 在 C++ 中返回结构数组

C++ 在 try block 中创建对象,然后将它们存储在 std::array 中

ios - GLKit的-drawRect : is not called during screen rotation

android - 我的目标选择 AI 是否高效?

javascript - Firebase 未找到云功能?

android - Firebase 上传/下载 pdf 文件

c++ - boost 智能指针

c++ - Visual Studio 2015 中没有 C++ 项目属性