Pacote PubNub para Flutter — PubNub Package for Flutter

Ricardo Ogliari
6 min readJun 23, 2020

Nos meus estudos sobre Mobile e Internet das Coisas, acabei conhecendo a PubNub, uma plataforma de troca de mensagens, ou, um serviço de mensageria. Usei ela profissionalmente em um aplicativo Android que ajudei a desenvolver, há alguns anos atrás.

In my studies on Mobile and Internet of Things, I met PubNub, a message exchange platform, or, a messaging service. I used it professionally in an Android application that I helped develop a few years ago.

Depois do uso profissional, outro ponto que me chamou a atenção foi a propaganda de que a plataforma tinha suporta para mais de 70 SDKs. Realmente é um número muito impressionante, permitindo que uma soluções IoT possa conectar uma TV, seu console de vídeo game, seu relógio e seu smartphone, além de qualquer outro dispositivo IoT conectado a um relé, por exemplo. Obviamente não consegui testar todas as 70 plataformas.

After professional use, another point that caught my attention was the advertisement that the platform had support for more than 70 SDKs. It really is a very impressive number, allowing an IoT solution to connect a TV, your video game console, your watch and your smartphone, in addition to any other IoT device connected to a relay, for example. Obviously I was not able to test all 70 platforms.

Porém, quando meus estudos iniciais com Flutter começaram, logo implementei o PubNub em um aplicativo IoT. Porém, não existia ainda um pacote para uso diretamente com DART. A solução naquele instante foi usar o Platform Channel para trocar dados com o código nativo e, desta forma, usar as bibliotecas para Android (Kotlin) e iOS (Swift).

However, when my initial studies with Flutter started, I implemented PubNub in an IoT application. However, there was not yet a package for use directly with DART. The solution at that moment was to use the Platform Channel to exchange data with the native code and, thus, use the libraries for Android (Kotlin) and iOS (Swift).

Contudo, na semana passada, dando uma olhada rápida no site da PubNub, descobri que já tem um pacote específico para DART e, consequentemente, Flutter. Fiquei muito feliz e logo comecei a codificar um aplicativo que fizesse uso deste pacote. Minha idéia foi um jogo da velha gamificado, que provavelmente estará nas lojas virtuais nos próximos dias (ou semanas).

However, last week, taking a quick look at the PubNub website, I discovered that it already has a specific package for DART and, consequently, Flutter. I was very happy and soon started to code an application that made use of this package. My idea was a game, which will probably be in the virtual stores in the coming days (or weeks).

E neste pequeno texto quero contar algumas especificidades dessa jornada, como problemas na documentação do pacote no próprio site da PubNub.

And in this short text I want to tell you some specifics of this journey, such as problems with the package documentation on the PubNub website itself.

Inicialmente será necessária criar uma conta, gratuitamente, no site do PubNub. Depois disso será possível criar um projeto no console da plataforma. E por fim, neste projeto, seremos presenteados com um conjunto de chaves que serão usadas no código DART. Lembrando que PubNub usa a idéia de Publisher-Subscriber, então, temos chaves para o publicador e para o assinante. Depois disso, no código, explicitamos isso da seguinte forma:

Initially it will be necessary to create an account, free of charge, on the PubNub website. After that it will be possible to create a project on the platform console. Finally, in this project, we will be presented with a set of keys that will be used in the DART code. Remembering that PubNub uses the Publisher-Subscriber idea, then we have keys for the publisher and the subscriber. After that, in the code, we explain this as follows:

final pubnub = PubNub(
defaultKeyset: Keyset(
subscribeKey: 'SUBSCRIBE_KEY',
publishKey: 'PUBLISH_KEY',
uuid: UUID('MY_UUID')));

var myChannel = pubnub.channel('my_channel');

Depois que temos acesso a um canal, criado por nós ou por terceiros, podemos assiná-lo e passar a ouvir qualquer mensagem publicada neste. Porém, o código presente na documentação é esse:

After we have access to a channel, created by us or by others, we can subscribe to it and start listening to any message published on it. However, the code in the documentation is this:

myChannel.subscribe().messages.listen((envelope) {
print(envelope.payload);
});

Infelizmente esse código da erro no Flutter. Sendo assim, tentei usar o famoso ctrl+space para ver as opções da classe. Para minha surpresa, isso não funcionou. Não sei precisar se é erro no meu ambiente ou no pacote, mas não tinha acesso a esta ajuda. Felizmente Flutter é open-source, então estudando o código fonte do próprio pacote do PubNub percebi que a assinatura do método subscribe, retorna um Future<Subscription>.

Unfortunately this code shows an error in Flutter. So, I tried to use the famous ctrl + space to see the class options. To my surprise, it didn’t work. I don’t know if it’s an error in my environment or in the package, but I didn’t have access to this help. Fortunately Flutter is open-source, so studying the source code of the PubNub package itself I realized that the subscription to the subscribe method, returns a Future <Subscription>.

Future<Subscription> subscribe({bool withPresence = false}) {
return _core.subscribe(
keyset: _keyset, channels: {name}, withPresence: withPresence);
}

Então, cheguei a este código, que fez funcionar de forma mágica. O then recebe como parâmetro um Subscription. Este, por sua vez, tem um Stream<Envelope>. E, para fechar o ciclo, o envelope tem o payload. Neste último, temos acesso aos dados publicados no canal, e capturados pelo código, que está atuando como assinante, neste momento.

So, I came up with this code, which made it work in a magical way. Then takes a Subscription as a parameter. This, in turn, has a Stream<Envelope>. And, to close the cycle, the envelope has the payload. In the payload, we have access to the data published on the channel, and captured by the code, which is currently acting as a subscriber.

myChannel.subscribe().then((subscription){
subscription.messages.listen((envelope){
String messageTap = envelope.payload['tap'];

...
});
});

Por fim, temos o código para publicar alguma mensagem no canal. O código é muito simples, apenas enviamos um dado no formato json para o método publish. O retorno é um PublishResult que, possui a variável isError. Com isso, fica fácil enviar o dado e gerenciar o sucesso ou falha do retorno. Ah, perceba o uso do await e do async na assinatura do método, devido a assincronidade do publish.

Finally, we have the code to post a message on the channel. The code is very simple, we just send data in json format to the publish method. The return is a PublishResult that has the variable isError. This makes it easy to send the data and manage the success or failure of the return. Ah, notice the use of await and async in the method signature, due to the publish’s asynchronity.

var response = await myChannel.publish({'action': 'new'});
if (!response.isError) {
...
}

Conclusão — Conclusion

O pacote do PubNub para Flutter mantém a simplicidade do próprio conceito do Publisher-Subscriber. Suas possibilidades são imensas e pode facilmente ajudar a enriquecer sua aplicação móvel. O único ponto negativo é a falta de acesso a documentação da classe. Porém, é até legal estudar o código fonte do pacote. E como o código está de fácil entendimento, foi fácil corrigir este problema. No futuro, vou tentar falar mais sobre este pacote abordando a codificação completa de um exemplo. Aguardem cenas dos próximos capítulos!

The PubNub Flutter package maintains the simplicity of the Publisher-Subscriber concept itself. Your possibilities are immense and you can easily help enrich your mobile application. The only downside is the lack of access to class documentation. However, it is even legal to study the source code of the package. And since the code is easy to understand, it was easy to fix this problem. In the future, I will try to talk more about this package by covering the complete coding of an example. Wait for scenes from the next chapters!

--

--