Particle.Subscribe using a class function as the callback

I’m trying to subscribe to a topic using a callback in the same class as the subscription. Here’s my non working code.

void ElectronProvisionConnection::provisioningWebhookHandler(const char *event, const char *data) 
{
  parseProvisionData(String(data));
}

bool ElectronProvisionConnection::doUpdate()
{
  Particle.subscribe(
    "myhook/topic", 
    provisioningWebhookHandler,    
    MY_DEVICES);                    
 };
}

When I compile I get the following error.

error: no matching function for call to 'CloudClass::subscribe(const char [37], <unresolved overloaded function type>, Spark_Subscription_Scope_TypeDef)'
           MY_DEVICES);           
                     ^

How do I pass the class function as the callback?

I’m compiling for the Electron.

The docs do provide a special overload for that use case

https://docs.particle.io/reference/firmware/photon/#particle-subscribe-

class Subscriber {
  public:
   Subscriber() {
      Particle.subscribe("some_event", &Subscriber::handler, this);
    }
    void handler(const char *eventName, const char *data) {
      Serial.println(data);
    }
};

Subscriber mySubscriber;

The reason is that non-static methods always need to be “linked” to the “owning” instance in order to be resolvable, which requires the function (like Particle.subscribe()) to know which instance that method belongs to.

3 Likes

Brilliant, thanks!

I am using this example for "class Subscriber", publishing event and not getting any data with handler (test webhook). I have tested publish/subscribe with no "class" only handler function and that is working. Can someone check if I am stupid for this and test on theirs devices!? OS 1.4.2

If using Web IDE can you post a SHARE THIS REVISION link to your project so that we can look it how you’ve done it exactly (including the triggering publish statement)?

Here it is…
(I commented only lines that I am using fr 3rd party sim)

https://go.particle.io/shared_apps/5dbd2de745d7ef00057d217c

Thanks for reply…

I’d try MY_DEVICES when you are publishing PRIVATE.

Granted, ALL_DEVICES would suggest to be a superset of MY_DEVICES but unfortunately it’s not :confused:
I’d even think that _DEVICES is somewhat confusing since it’s not really a “device” but an “event” you are subscribing to, so PRIVATE_EVENTS and PUBLIC_EVENTS would make more sense IMO.

I tried already MY_DEVICES and ALL_DEVICES but it is not working

What device are you using?
Does your Webhook work as expected?
How does your Webhook definition look?
Do you see the hook-response/mockyOk event in Console?

I am using electron, webhook works and I see published event and hook-response/mockyOk in console

Yup, I missed that part.
You are only instantiating the object locally in setup() once you fall out of that function the object will vanish and the subscription with it.

When you do it this way it should work

Subscriber* mySubscriber;
void setup() {
  mySubscriber = new Subscriber();
}
1 Like

I will try but I think at the begining I had subsriber defined globally.

Ok...now works!
At the moment I tested with global object I had ALL_DEVICES in subscribtion and that was the reason that didn't work! I agree with you that ALL_DEVICES should be a superset of MY_DEVICES!!! I didn't know that.
Thanks for your help.

1 Like