Connecting to HIVEMQ using Flutter and mqtt_client

I am having problems establishing connection to the HIVEMQ broker.
Initially, just trying to initiate a connection .
I am using the Flutter pub package ‘mqtt_client’

I have tried to follow the video and the github example but still not able to establish connection

Be great if the HIVEMQ team could provide an updated "cookbook’ recipe using Flutter and the ‘mqtt_client’ package to connect, sub/pub to HIVEMQ. This would be a huge help to the entire development community.


import ‘package:flutter/material.dart’;
import ‘package:mqtt_client/mqtt_client.dart’ as mqtt;

void main() {
runApp(const MyApp());
}

class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: ‘MQTT Demo’,
home: const MyHomePage(),
);
}
}

class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State createState() => _MyHomePageState();
}

class _MyHomePageState extends State {

String broker = ‘b20661310cc048cfb9583aac0be45323.s1.eu.hivemq.cloud’;
int port = 8883;
String username = ‘myUsername’;
String passwd = ‘myPassword’;
String clientIdentifier = ‘myId’;

late mqtt.MqttClient client;
// mqtt.MqttConnectionState connectionState;

@override
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
return Scaffold(
appBar: AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text(‘MQTT Cient Test’),
),
body: Center(
// Center is a layout widget. It takes a single child and positions it
// in the middle of the parent.
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
‘MQTT Client’,
),
TextButton(onPressed: () {
_connect();
},
child: Text(
‘Connect’
),)
],
),
),

);

}
}

void _connect() async {
/// First create a client, the client is constructed with a broker name, client identifier
/// and port if needed. The client identifier (short ClientId) is an identifier of each MQTT
/// client connecting to a MQTT broker. As the word identifier already suggests, it should be unique per broker.
/// The broker uses it for identifying the client and the current state of the client. If you don’t need a state
/// to be hold by the broker, in MQTT 3.1.1 you can set an empty ClientId, which results in a connection without any state.
/// A condition is that clean session connect flag is true, otherwise the connection will be rejected.
/// The client identifier can be a maximum length of 23 characters. If a port is not specified the standard port
/// of 1883 is used.
/// If you want to use websockets rather than TCP see below.
///

var client = mqtt.MqttClient(‘b20661310cc048cfb9583aac0be45323.s1.eu.hivemq.cloud’, ‘’);
client.port = 1883;

/// A websocket URL must start with ws:// or wss:// or Dart will throw an exception, consult your websocket MQTT broker
/// for details.
/// To use websockets add the following lines -:
/// client.useWebSocket = true;
/// client.port = 80; ( or whatever your WS port is)
/// Note do not set the secure flag if you are using wss, the secure flags is for TCP sockets only.
/// Set logging on if needed, defaults to off
client.logging(on: true);

/// If you intend to use a keep alive value in your connect message that is not the default(60s)
/// you must set it here
client.keepAlivePeriod = 30;

/// Add the unsolicited disconnection callback
// client.onDisconnected = _onDisconnected;

/// Connect the client, any errors here are communicated by raising of the appropriate exception. Note
/// in some circumstances the broker will just disconnect us, see the spec about this, we however will
/// never send malformed messages.

try {
await client.connect(‘username’,‘myPassword’);
} catch (e) {
print(e);
// _disconnect();
}

}

I found this repo

However, we get this error:
Error: Cannot run with sound null safety, because the following dependencies
don’t support null safety:

  • package:mqtt_client
  • package:event_bus
  • package:crypto
  • package:convert

For solutions, see Unsound null safety | Dart

I just cloned the repo from: GitHub - hivemq-cloud/mqtt.dart-client-example: Complete example project to get started with MQTT.dart on HiveMQ Cloud
ran the main() as instructed in the Readme file.
Result:

  1. we do see in the Dart terminal that it is working and echoing back
    hive2

  2. However we can not see the message in the HIVE Web Client.
    Subscribed to the ‘testtopic’

We would expect to see a message = ‘hello’ in the HIVE Web Client

Any hints as to why we are not seeing the message in the Hive Web Client

Figured out part of problem:
The topic is ‘Dart/Mqtt_client/testtopic’ . We were erroneously subscribing to ‘testtopic’ in the Hive Web Client

Hi octava,

Were you able to resolve all the issues? If not, where are you now in terms of what is still not working? (any updated error messages or output etc)

Thanks,
Seth - HiveMQ Support

Hi Seth
We are able to make progress.

I realize this is beyond the scope of the HiveMQ forum.

We are publishing new message to the topic every 5 seconds as a test.
We are able to ‘subscribe’ to the HiveMQ topic and receiving the new message and it is showing correctly in the terminal from print(message()

The problem is now a Flutter specific problem .
We have edited the MQTTClientWrapper and extended changeNotifier.
In the subscribe we are issuing notifyListeners() and passing the data down the widget with a Provider.

class MQTTClientWrapper extends ChangeNotifier {

MqttServerClient client;
MqttCurrentConnectionState connectionState = MqttCurrentConnectionState.IDLE;
MqttSubscriptionState subscriptionState = MqttSubscriptionState.IDLE;

String myData = ‘InitialValue’ ; //Need to pass updates to widget, using Provider

void _subscribeToTopic(String topicName) {
print(‘Subscribing to the $topicName topic’);
client.subscribe(topicName, MqttQos.atMostOnce);

// print the message when it is received
client.updates.listen((List<MqttReceivedMessage<MqttMessage>> c) {
  final MqttPublishMessage recMess = c[0].payload;
  var message = MqttPublishPayload.bytesToStringAsString(recMess.payload.message);

  print('YOU GOT A NEW MESSAGE:');
  print(message);  // Displays message correctly

  myData = message;
  notifyListeners();

});

}

However, the Provider to the widget is not receiving the updates.

Is there any reason why the notifyListners() is not working inside the client.updates.listen()?
Thought maybe if Seth who wrote the library may see this and provide some guidance.