Webhook is triggered even though Particle.publish() returned false

I use an electron with firmware 0.7.0 to collect data offline. It connects every hour to the cloud and publishes the collected data as encoded binary (Z85) in the events data string. Then I use a Webhook to forward the data to my server where the event data string is decoded and stored into a database. It is important that I do not loose any event data therefore my device code retries a Particle.publish() if it returns false.

void publishMessage(const char* message) {
   int republishLimit = 10;
   bool ack = false;
   while(!ack) {
      ack = Particle.publish(mEventName, message, WITH_ACK);
      if(!ack) {
         if(republishLimit <= 0) {
            Log.error("republish limit reached => skip message!");
         Log.warn("publish failed => sleep and try to re-publish");

I now see on my server that sometimes I get duplicated data because the same data is received more than once. I see that I receive multiple requests from the webhook with same data but another published_at time. Therefore I concluded that the webhook is sometimes triggered even though Particle.publish() returned false on the device side.
I did not expect this.

So my question is:

Is this expected behavior and I need to add additional checks/means to my server code to avoid duplicated data or is this considered a bug of Particle.publish()/Webhooks and should be fixed in Particle firmware and/or cloud?

Thanks and regards

This is a known thing, but you’re best off de-duping on the server.

When you use WITH_ACK and check the result with 0.7.0 and later, a few things happen:

  • The call will block until the ACK is received, or 20 seconds, whichever is shorter.
  • If no ACK is received in 20 seconds, false is returned.

However, that publish is buffered. If the cloud subsequently reconnects, some number of buffered publishes will go out. So even though publish returned false, the publish will go out. Also, if you do this with more than one publish, they will likely arrive out of order. I’m not sure of the exact number that can be buffered.

It’s explained a bit more in the WITH_ACK section here:

1 Like