diff --git a/esphome/components/mqtt/mqtt_backend_esp32.cpp b/esphome/components/mqtt/mqtt_backend_esp32.cpp index 2d4e6802f2..9e89b3d493 100644 --- a/esphome/components/mqtt/mqtt_backend_esp32.cpp +++ b/esphome/components/mqtt/mqtt_backend_esp32.cpp @@ -138,13 +138,16 @@ void MQTTBackendESP32::mqtt_event_handler_(const Event &event) { this->on_publish_.call((int) event.msg_id); break; case MQTT_EVENT_DATA: { - static std::string topic; if (event.topic.length() > 0) { - topic = event.topic; + // When a single message arrives as multiple chunks, the topic will be nullptr + // on any but the first message, leading to event.topic being an empty string. + // To ensure handlers get the correct topic, cache the last seen topic to + // simulate always receiving the topic from underlying library + topic_cache_ = event.topic; } - ESP_LOGV(TAG, "MQTT_EVENT_DATA %s", topic.c_str()); - this->on_message_.call(event.topic.length() > 0 ? topic.c_str() : nullptr, event.data.data(), event.data.size(), - event.current_data_offset, event.total_data_len); + ESP_LOGV(TAG, "MQTT_EVENT_DATA %s", topic_cache_.c_str()); + this->on_message_.call(topic_cache_.c_str(), event.data.data(), event.data.size(), event.current_data_offset, + event.total_data_len); } break; case MQTT_EVENT_ERROR: ESP_LOGE(TAG, "MQTT_EVENT_ERROR"); diff --git a/esphome/components/mqtt/mqtt_backend_esp32.h b/esphome/components/mqtt/mqtt_backend_esp32.h index a4ee96ca59..ddeb98da96 100644 --- a/esphome/components/mqtt/mqtt_backend_esp32.h +++ b/esphome/components/mqtt/mqtt_backend_esp32.h @@ -155,6 +155,7 @@ class MQTTBackendESP32 final : public MQTTBackend { bool clean_session_; optional ca_certificate_; bool skip_cert_cn_check_{false}; + std::string topic_cache_; // callbacks CallbackManager on_connect_;