<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: FlutterExplained</title>
    <description>The latest articles on DEV Community by FlutterExplained (@myracledesign).</description>
    <link>https://dev.to/myracledesign</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F256143%2Ff985d0b6-dd14-4450-802a-4f52b8b7610c.jpeg</url>
      <title>DEV Community: FlutterExplained</title>
      <link>https://dev.to/myracledesign</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/myracledesign"/>
    <language>en</language>
    <item>
      <title>A terminal real time application with Dart Sockets</title>
      <dc:creator>FlutterExplained</dc:creator>
      <pubDate>Wed, 27 Jul 2022 08:59:00 +0000</pubDate>
      <link>https://dev.to/myracledesign/a-terminal-real-time-application-with-dart-sockets-3o7j</link>
      <guid>https://dev.to/myracledesign/a-terminal-real-time-application-with-dart-sockets-3o7j</guid>
      <description>&lt;p&gt;We already covered in another &lt;a href="https://flutter-explained.dev/deploy-dart-server-on-heroku"&gt;Article&lt;/a&gt; what an HTTP call is and how it works in a Client - Server Architecture. But today we want to have a look how we can keep an connection open between the Client and the Server in order to implement an Real Time Application.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/cpEYw8HuoxI"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Why do we need Sockets
&lt;/h2&gt;

&lt;p&gt;But what would be the benefit of Sockets compared to the standard HTTP Request / Response method? In modern applications, we want real-time data, and who thinks now at Firebase is correct. &lt;/p&gt;

&lt;p&gt;Before we had the benefit of WebSockets or Sockets, we had to wait until the Server finished a task and make another request to get the Data. Because the Server never told us, that we were ready with the new data. Therefore, developers all around the world discovered some quite exciting workarounds like Pooling. At Polling a client made a request every period (200+ ms) to check, if there are new data present. Thanks to WebSockets and Sockets we have the chance to reduce the load of our servers because we can reduce the calls needed. With that the server can directly notify the client of the new information. Real-Time applications are born. &lt;/p&gt;

&lt;h2&gt;
  
  
  Sockets vs. WebSockets
&lt;/h2&gt;

&lt;p&gt;At the beginning of my journey I tried to use &lt;a href="https://pub.dev/packages/shelf_web_socket"&gt;Shelf_WebSockets&lt;/a&gt; and connect with my two Terminals and the result was,... nothing. Interesting enough I was able to connect via the terminal clients to the server but whenever I send a message it was just not visible and the server did not show anything.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/573xlmlwok2s/4cCI6viOhHv1o4nz8u6KQV/f60b5cc79a91870e9aae17b9dde6f4cb/Screenshot_2022-07-04_at_16.15.26.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/573xlmlwok2s/4cCI6viOhHv1o4nz8u6KQV/f60b5cc79a91870e9aae17b9dde6f4cb/Screenshot_2022-07-04_at_16.15.26.png" alt="Example with Websockets"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After a long time of learning and debugging I found out that my Terminal used &lt;a href="https://api.dart.dev/stable/2.17.3/dart-io/Socket-class.html"&gt;Dart:io&lt;/a&gt; and needs that a Server works with the same TCP Sockets. While the WebSocket Server was able to allow the connections it was unable to understand the messages the Terminals tried to send. &lt;/p&gt;

&lt;p&gt;Why is that the case, well WebSockets are an upgraded HTTP request that allows the open connection between a client and a server. WebSockets are usually used to connect from a Browser or an UI to the Server and this made it probalmatic. There are packages out there that allow Terminals to connect against an WebSocket server but I did not use them. Therefore I needed to change my WebSocket Server to an TCP Socket Server. &lt;/p&gt;

&lt;p&gt;So the rest of the Tutorial we will only use a Socket Server and Socket Clients but the same thing can be done with WebSocket Server and an WebSocket Client like for example &lt;a href="https://pub.dev/packages/websocket_manager"&gt;websocket_manager&lt;/a&gt; that allows Flutter to connect against a WebSocket Server. &lt;/p&gt;

&lt;p&gt;If you want to know more about Sockets vs. WebSockets I can recommend you to read the mdn post about &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API"&gt;WebSockets&lt;/a&gt; and the &lt;a href="https://stackoverflow.com/questions/4973622/difference-between-socket-and-websocket"&gt;StackOverflow&lt;/a&gt; answer. Great now that we have that out of the way let's see how we can develop our application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;p&gt;The best part of the implementation we will now see is that we do not rely on any package. To make this possible default Dart is enough to make it work and that is by any means awesome. The only package I added is absolutly optional and is called &lt;a href="https://pub.dev/packages/ansicolor"&gt;ansicolor&lt;/a&gt; and allows to make prints in the console a bit more colorful. &lt;/p&gt;

&lt;p&gt;I created a basic barebone Dart project without anything inside but a terminal executable. Because we do not need the boilerplate from the Server app because we want to use Sockets :). &lt;/p&gt;

&lt;p&gt;![[Pasted image 20220706134649.png]]&lt;/p&gt;

&lt;p&gt;Now I delete everything in the bin folder and created three files &lt;code&gt;client.dart&lt;/code&gt;, &lt;code&gt;server.dart&lt;/code&gt; and &lt;code&gt;terminal_service.dart&lt;/code&gt;. In the &lt;code&gt;client.dart&lt;/code&gt; we will collect all information about the client, how he connects to the server and the message he sends. At the end we will be able to start multiple clients against a single server. The second file is the &lt;code&gt;server.dart&lt;/code&gt; inside here we write everything to receive messages from multiple clients and notify all clients that there happens something new. Last but not least we have the &lt;code&gt;terminal_service.dart&lt;/code&gt; this is just a mini service that contains different print functions for different colors. The result after the tutorial will look something like this.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/573xlmlwok2s/E4jewvjn1J370kWe37HUZ/5bf8526d48f85911f779e296e2c8487a/Screenshot_2022-07-04_at_22.27.40.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/573xlmlwok2s/E4jewvjn1J370kWe37HUZ/5bf8526d48f85911f779e296e2c8487a/Screenshot_2022-07-04_at_22.27.40.png" alt="Socket Server allows two connections - Solution"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Setup the Server
&lt;/h3&gt;

&lt;p&gt;First we start as always with a main function inside here we want to find the local ip address and we allow to find dart just an unused IP address. Then we create a ServerSocket and bind the ip and a port in our case the port is fixated on 3000. after that we just let the server listen to incoming connections, so whenever someone connects to the server the callback in &lt;code&gt;server.listen(callback)&lt;/code&gt; will be executed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;  
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;InternetAddress&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;anyIPv4&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;  
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;ServerSocket&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;bind&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;  

  &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Server is running on: &lt;/span&gt;&lt;span class="si"&gt;${ip.address}&lt;/span&gt;&lt;span class="s"&gt;:3000"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;  

  &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;listen&lt;/span&gt;&lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;Socket&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;  
    &lt;span class="n"&gt;handleConnection&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;  
  &lt;span class="o"&gt;});&lt;/span&gt;  
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whenever a client is connecting to our Server we call the method &lt;code&gt;handleConnection&lt;/code&gt; inside of which we want now to inform the Server that there is an incoming connection. The Socket we receive in the handleConnection is the information how to communicate to that specific client and if you want for example to create multiple players you can save that socket to have a reference between player and socket to send messages between specific players. Now we have to listen to the client if the client is sending the server some messages.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Socket&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;clients&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[];&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;handleConnection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Socket&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;  
  &lt;span class="n"&gt;printGreen&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;  
    &lt;span class="s"&gt;"Server: Connection from &lt;/span&gt;&lt;span class="si"&gt;${client.remoteAddress.address}&lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="si"&gt;${client.remotePort}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;  
  &lt;span class="o"&gt;);&lt;/span&gt;  

  &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;listen&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="o"&gt;);&lt;/span&gt;  
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before we had already &lt;code&gt;server.listen&lt;/code&gt; where the server waited for connections, now we have &lt;code&gt;client.listen&lt;/code&gt; so we on the server wait for the client to send us some notifications. the &lt;code&gt;client.listen&lt;/code&gt; function has some information we have to pass in. The first part is how to handle messages from the client. So what we will do is we receive a Uint8List message that is just a basic ByteString, and because we will be in full control of the client we know that this will be a basic string so we can transcode it with &lt;code&gt;String.fromCharCodes(data)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In that message we want that our users will send the player name so we can inform every client that already connected to the server&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;listen&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;  
  &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Uint8List&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;  
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromCharCodes&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;  

    &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;clients&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;  
      &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Server: &lt;/span&gt;&lt;span class="si"&gt;$message&lt;/span&gt;&lt;span class="s"&gt; joined the party!"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;  
    &lt;span class="o"&gt;}&lt;/span&gt;  

    &lt;span class="n"&gt;clients&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;  
    &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Server: You are logged in as: &lt;/span&gt;&lt;span class="si"&gt;$message&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;  
  &lt;span class="o"&gt;},&lt;/span&gt;
  &lt;span class="nl"&gt;onError:&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;
  &lt;span class="nl"&gt;onDone:&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Implement the Client
&lt;/h2&gt;

&lt;p&gt;First we create in our Dart Project another file called &lt;code&gt;client.dart&lt;/code&gt;. Here we will implement the client application that will connect to our Server. The client works similar to the Server and should be a standalone Dart application. Therefore, we need another &lt;code&gt;main&lt;/code&gt; function. In this &lt;code&gt;main&lt;/code&gt; function we connect with a Socket to our Server with the IP we get from the server command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(){&lt;/span&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Socket&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;connect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"0.0.0.0"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Connected to &lt;/span&gt;&lt;span class="si"&gt;${socket.remoteAddress.address}&lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="si"&gt;${socket.remotePort}&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When we execute the &lt;code&gt;client.dart&lt;/code&gt; file now without anything further we will get already the information on our Terminal where the Server is running, it should look something like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ssh"&gt;&lt;code&gt;&lt;span class="err"&gt;➜&lt;/span&gt; &lt;span class="k"&gt;dart&lt;/span&gt; ./bin/client.dart
&lt;span class="k"&gt;Connected&lt;/span&gt; to: &lt;span class="m"&gt;127&lt;/span&gt;.0.0.1:3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ssh"&gt;&lt;code&gt;&lt;span class="err"&gt;➜&lt;/span&gt; &lt;span class="k"&gt;dart&lt;/span&gt; ./bin/server.dart
&lt;span class="k"&gt;Server&lt;/span&gt; is running on: &lt;span class="m"&gt;0&lt;/span&gt;.0.0.0:3000
&lt;span class="k"&gt;Server&lt;/span&gt;: Connection from &lt;span class="m"&gt;127&lt;/span&gt;.0.0.1:53419
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Therefore we can see that the Server already receives the connection, and keeps the connection open for the ip 127.0.0.1:53419. This is in our case also the same computer but the IP and the Port could be completly different for your implementation. Great so the Connection is already stable so lets send some messages from the client to the Server and see how we can handle them. For that we will ask the User for his name and send the information to the Server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Ask user for its username&lt;/span&gt;

&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;  

&lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Client: Please enter your username"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stdin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;readLineSync&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEmpty&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We first define a variable &lt;code&gt;username&lt;/code&gt; that could be null and in the &lt;code&gt;do-while-loop&lt;/code&gt; we ask the user for a terminal input to enter the username, if the username is null or empty we ask him again until we get the info we need. After that we call &lt;code&gt;socket.write(username);&lt;/code&gt; which sends the information directly to the Server.  But if we restart the Server and the client now we will see that nothing has changed. The message is now only send to the server and if we check again the server we see that we send the message to the client. &lt;br&gt;
&lt;code&gt;client.write("Server: You are logged in as: $message");&lt;/code&gt;&lt;br&gt;
The client on the other hand does not listen to server messages and is not able to show what the Server send, yet. So let us make the Client smarter and allow it to receive messages send by the Server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;listen&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Uint8List&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;serverResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromCharCodes&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;printGreen&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Client &lt;/span&gt;&lt;span class="si"&gt;$serverResponse&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;},&lt;/span&gt;
    &lt;span class="nl"&gt;onError:&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Client: &lt;/span&gt;&lt;span class="si"&gt;$error&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;destroy&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;},&lt;/span&gt;
    &lt;span class="nl"&gt;onDone:&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Client: Server left.'&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;destroy&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;},&lt;/span&gt;
&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we check the socket we can see that it provides also the &lt;code&gt;listen&lt;/code&gt; method and also here we have the chance to implement the same three methods like on the Server side. Therefore we implemented them nearly the same. The only difference is the &lt;code&gt;onData&lt;/code&gt; method that is now receiving the message and directly prints them into the console.&lt;/p&gt;

&lt;p&gt;If we start up now the Server and Client we should be able to see something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ssh"&gt;&lt;code&gt;&lt;span class="err"&gt;➜&lt;/span&gt; &lt;span class="k"&gt;dart&lt;/span&gt; ./bin/server.dart
&lt;span class="k"&gt;Server&lt;/span&gt; is running on: &lt;span class="m"&gt;0&lt;/span&gt;.0.0.0:3000
&lt;span class="k"&gt;Server&lt;/span&gt;: Connection from &lt;span class="m"&gt;127&lt;/span&gt;.0.0.1:54384
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ssh"&gt;&lt;code&gt;&lt;span class="err"&gt;➜&lt;/span&gt; &lt;span class="k"&gt;dart&lt;/span&gt; ./bin/client.dart
&lt;span class="k"&gt;Server&lt;/span&gt;: Connected to: &lt;span class="m"&gt;127&lt;/span&gt;.0.0.1:3000
&lt;span class="k"&gt;Client&lt;/span&gt;: Please enter your username
&lt;span class="k"&gt;Max&lt;/span&gt;
&lt;span class="k"&gt;Client&lt;/span&gt; Server: You are logged in as: Max
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And if we create another client the following will happen:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ssh"&gt;&lt;code&gt;&lt;span class="err"&gt;➜&lt;/span&gt; &lt;span class="k"&gt;dart&lt;/span&gt; ./bin/client.dart 
Server: Connected to: &lt;span class="m"&gt;127&lt;/span&gt;.0.0.1:3000
&lt;span class="k"&gt;Client&lt;/span&gt;: Please enter your username
&lt;span class="k"&gt;Mahtab&lt;/span&gt;
&lt;span class="k"&gt;Client&lt;/span&gt; Server: You are logged in as: Mahtab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ssh"&gt;&lt;code&gt;&lt;span class="err"&gt;➜&lt;/span&gt; &lt;span class="k"&gt;dart&lt;/span&gt; ./bin/client.dart
&lt;span class="k"&gt;Server&lt;/span&gt;: Connected to: &lt;span class="m"&gt;127&lt;/span&gt;.0.0.1:3000
&lt;span class="k"&gt;Client&lt;/span&gt;: Please enter your username
&lt;span class="k"&gt;Max&lt;/span&gt;
&lt;span class="k"&gt;Client&lt;/span&gt; Server: You are logged in as: Max
&lt;span class="k"&gt;Client&lt;/span&gt; Server: Mahtab joined the party!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ssh"&gt;&lt;code&gt;&lt;span class="err"&gt;➜&lt;/span&gt; &lt;span class="k"&gt;dart&lt;/span&gt; ./bin/server.dart
&lt;span class="k"&gt;Server&lt;/span&gt; is running on: &lt;span class="m"&gt;0&lt;/span&gt;.0.0.0:3000
&lt;span class="k"&gt;Server&lt;/span&gt;: Connection from &lt;span class="m"&gt;127&lt;/span&gt;.0.0.1:54384
&lt;span class="k"&gt;Server&lt;/span&gt;: Connection from &lt;span class="m"&gt;127&lt;/span&gt;.0.0.1:54415
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Great with that we have now a successful Socket Server running and multiple clients connected. This allows us now to create amazing applications that needs the real time experience. That can be integrated in Games but also in Tools where collaboration is key.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://codeberg.org/Flutter-Explained/sockets-tutorial-dart"&gt;tutorial project&lt;/a&gt; can be found on &lt;a href="https://codeberg.org/Flutter-Explained"&gt;Codeberg&lt;/a&gt;, feel free to check it out and if there are any toughts please let us know. Thanks for reading and till the next post.&lt;/p&gt;

</description>
      <category>dart</category>
      <category>flutter</category>
      <category>terminal</category>
      <category>sockets</category>
    </item>
    <item>
      <title>Deployment of a Dart Server on Heroku</title>
      <dc:creator>FlutterExplained</dc:creator>
      <pubDate>Sat, 09 Apr 2022 14:49:23 +0000</pubDate>
      <link>https://dev.to/myracledesign/deployment-of-a-dart-server-on-heroku-3alf</link>
      <guid>https://dev.to/myracledesign/deployment-of-a-dart-server-on-heroku-3alf</guid>
      <description>&lt;p&gt;Running the first server is a fantastic experience for every developer. It gives you many options and possibilities and improves your general understanding of software engineering. After we learned in my previous &lt;a href="https://www.youtube.com/watch?v=kYM-wlOhQ3I&amp;amp;list=PLq83k-ITj6lQuw6asmdEbuNCV6vVwqT5c"&gt;videos&lt;/a&gt; already how to start a server locally, we want in this article to learn how to make our services available on the world wide web so that you can access them from every device.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://odysee.com/%24/embed/client-server-architecture-build-your/88592c3f4eb4ffd136b1c5b949638dc1ea35b446?r=BJgwk1iRu2HVxyUNS1oX38aRZPJ1YbT9" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--2mMk0xFd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cards.odycdn.com/aHR0cHM6Ly90aHVtYm5haWxzLmxicnkuY29tL2tZTS13bE9oUTNJ.jpg" height="360" class="m-0" width="640"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://odysee.com/%24/embed/client-server-architecture-build-your/88592c3f4eb4ffd136b1c5b949638dc1ea35b446?r=BJgwk1iRu2HVxyUNS1oX38aRZPJ1YbT9" rel="noopener noreferrer" class="c-link"&gt;
          Client &amp;amp; Server Architecture - Build your first Web Server with Dart
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Today, we want to look into a client-server architecture, and we will create our first server with dart &amp;amp; shelf.

Chapters:
00:00 Welcome to the Flutter Explained
00:45 Theorie what is a Client / What...
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--WS4io2br--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--xVAjbsrV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_48/https://odysee.com/public/favicon-spaceman.png" width="48" height="48"&gt;
        odysee.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Deployment
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Software deployment includes all activities that make a software system available to use. - &lt;a href="https://en.wikipedia.org/wiki/Software_deployment"&gt;Wikipedia&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In our use case, we want to access our server from every device connected to the Internet and not only our local device in front of us. In professional teams, that task is automated in most cases and transforms quickly. Into continuous deployment where you work on your code, push to a repository, and the deployment gets automatically triggered. But in smaller teams or smaller organizations, the preferred way is usually for a skilled professional to perform that task. And because we are skilled professionals, we do exactly that today.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;We have to prepare just a few things to get started in the beautiful world of deployment. The first thing that we need is a physical server that will run our software server :). For this reason, we will use &lt;a href="https://www.heroku.com/"&gt;Heroku&lt;/a&gt;, because it allows us to run our software for free in a small server &lt;a href="https://en.wikipedia.org/wiki/Virtual_machine"&gt;Virtual Machine (VM)&lt;/a&gt; that we can scale up if we want.&lt;/p&gt;

&lt;p&gt;We also need a software service that we already built in the videos mentioned above. The service we want to deploy will use the &lt;a href="https://pub.dev/packages/shelf"&gt;shelf server&lt;/a&gt; from Dart &lt;br&gt;
 hat we already run locally and make our first requests.&lt;br&gt;
But this will also work if you use a &lt;a href="https://aqueduct.io/"&gt;aqueduct server&lt;/a&gt; or a &lt;a href="https://www.theconduit.dev/"&gt;conduit server&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Summary of what we need today:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Heroku Account&lt;/li&gt;
&lt;li&gt;Running Software Server&lt;/li&gt;
&lt;li&gt;No previous knowledge about deployment processes&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;After you successfully create an account on Heroku, you will probably see a page that welcomes you to Heroku. From here,&lt;br&gt;
you could also create a new app, but we will do it with the &lt;a href="https://devcenter.heroku.com/articles/heroku-cli"&gt;Heroku CLI&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Heroku CLI
&lt;/h3&gt;

&lt;p&gt;Now that we have that covered let us jump right into it. To begin our journey to deploy something on Heroku, we need to&lt;br&gt;
install the &lt;a href="https://devcenter.heroku.com/articles/heroku-cli"&gt;&lt;code&gt;Heroku CLI&lt;/code&gt;&lt;/a&gt;. Then, check out the link of the Heroku CLI and select the system that fits your operating system.&lt;/p&gt;

&lt;p&gt;Great, the Heroku CLI will help us deploy our Server to the Heroku server. After the installation, we first have to &lt;code&gt;login&lt;/code&gt; against the Heroku system. For that, execute &lt;code&gt;Heroku login&lt;/code&gt; in your terminal. After executing the command, your default web browser will open and allow you to log in to Heroku.&lt;/p&gt;
&lt;h3&gt;
  
  
  Create a new Heroku app
&lt;/h3&gt;

&lt;p&gt;The most convenient way to create a new Heroku app is via the CLI. For that, open a terminal and navigate to your workspace in which your project is. In our example, it will be in &lt;code&gt;~/dev/dart-server&lt;/code&gt;. Now we want to create our app. We execute &lt;code&gt;Heroku create &amp;lt;name-of-your-app&amp;gt;&lt;/code&gt; in our example. We call the app &lt;code&gt;fe-dart-server&lt;/code&gt;. If you do not pass a name, it will create a random app name for you.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;heroku create fe-dart-server
Creating ⬢ fe-dart-server... done
https://fe-dart-server.herokuapp.com/ | https://git.heroku.com/fe-dart-server.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As a result, Heroku delivers us two URLs. The first one is the URL directly to our app. Currently, we do not have an application running on &lt;code&gt;https://fe-dart-server.herokuapp.com/&lt;/code&gt;.Therefore, you will find the &lt;br&gt;
 ocumentation link of Heroku if you open it. The second link is the internal git server of Heroku, from which it will use your source code to build the project. We will need to add a new remote to git to push our Dart project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# If you have not initialized your project with git
git init
git add remote heroku https://git.heroku.com/fe-dart-server.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;** Hint: It could be that if your project was already in git, it was already added with the Heroku create command**&lt;/p&gt;

&lt;p&gt;Now that your app is registered to Heroku, we have to set up a &lt;a href="https://devcenter.heroku.com/articles/buildpacks"&gt;buildpack&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Heroku works
&lt;/h2&gt;

&lt;p&gt;Now it is essential to know how Heroku works. A build pack is responsible for transforming your deployed source code into a &lt;code&gt;slug&lt;/code&gt;, which can then be executed by a &lt;code&gt;dyno&lt;/code&gt;. You can read more about how Heroku works &lt;a href="https://devcenter.heroku.com/articles/how-heroku-works"&gt;here&lt;/a&gt;. So before we go deeper into the topic, let's quickly check what a slug and a dyno are.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A &lt;code&gt;slug&lt;/code&gt; is a bundle of your source, fetched dependencies, the language runtime, and compiled/generated output of the build system - ready for execution.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Dynos&lt;/code&gt; are isolated, virtualized Unix containers that provide the environment required to run an application.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Source: &lt;a href="//devcenter.heroku.com"&gt;devcenter.heroku.com&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Set up a build pack for Dart
&lt;/h2&gt;

&lt;p&gt;Unfortunately, Heroku is not yet supporting &lt;code&gt;Dart&lt;/code&gt; with an official build pack. Therefore, we have to take advantage of&lt;br&gt;
the fantastic Dart &amp;amp; Flutter Community, which has created already a build pack that we can use. We will use in this tutorial the most starred build pack by &lt;a href="https://github.com/igrigorik"&gt;igrigorik&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To use the build pack, we will have to tell Heroku to use a specific download URL for the Dart language and configure the build pack we want to use. To find a Dart SDK URL, we  check the &lt;a href="https://dart.dev/get-dart/archive"&gt;Dart Archive&lt;/a&gt; page. Then, we select &lt;code&gt;Linux&lt;/code&gt; and the version we would like to install. This example case is version 2.16.2`, which is the current version. Now right, click on Dart SDK and copy the link address. We will need it in a second.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--roUHsV2e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://flutter-explained.dev/static/303be974cb8c311c10d40930ea2fe745/48171/dart-archive.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--roUHsV2e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://flutter-explained.dev/static/303be974cb8c311c10d40930ea2fe745/48171/dart-archive.png" alt="How to get a Dart download URL" width="880" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now it is time to set the Dart URL and our &lt;code&gt;BUILDPACK_URL&lt;/code&gt; for our Heroku app by executing in our terminal.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`&lt;br&gt;
heroku config:set DART_SDK_URL=&lt;a href="https://storage.googleapis.com/dart-archive/channels/stable/release/2.16.2/sdk/dartsdk-linux-x64-release.zip"&gt;https://storage.googleapis.com/dart-archive/channels/stable/release/2.16.2/sdk/dartsdk-linux-x64-release.zip&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Setting DART_SDK_URL and restarting ⬢ fe-dart-server... done, v3&lt;br&gt;
DART_SDK_URL: &lt;a href="https://storage.googleapis.com/dart-archive/channels/stable/release/2.16.2/sdk/dartsdk-linux-x64-release.zip"&gt;https://storage.googleapis.com/dart-archive/channels/stable/release/2.16.2/sdk/dartsdk-linux-x64-release.zip&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;heroku config:add BUILDPACK_URL=&lt;a href="https://github.com/igrigorik/heroku-buildpack-dart.git"&gt;https://github.com/igrigorik/heroku-buildpack-dart.git&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Setting BUILDPACK_URL and restarting ⬢ fe-dart-server... done, v4&lt;br&gt;
BUILDPACK_URL: &lt;a href="https://github.com/igrigorik/heroku-buildpack-dart.git"&gt;https://github.com/igrigorik/heroku-buildpack-dart.git&lt;/a&gt;&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now it is time to push our source code to Heroku by pushing our source code to the remote git that we got when we created our Heroku app.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&lt;br&gt;
git add .                           # Adds all files to git in this repository&lt;br&gt;
git push --set-upstream heroku main # Sets the upstream branch to heroku main and pushes all files&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If you are doing it in the terminal, Heroku will give you a lot of logging information about the build process.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&lt;br&gt;
remote: -----&amp;gt; Discovering process types&lt;br&gt;
remote:        Procfile declares types -&amp;gt; (none)&lt;br&gt;
remote:&lt;br&gt;
remote: -----&amp;gt; Compressing...&lt;br&gt;
remote:        Done: 195.9M&lt;br&gt;
remote: -----&amp;gt; Launching...&lt;br&gt;
remote:        Released v7&lt;br&gt;
remote:        https://fe-dart-server.herokuapp.com/ deployed to Heroku&lt;br&gt;
remote:&lt;br&gt;
remote: Verifying deploy... done.&lt;br&gt;
To https://git.heroku.com/fe-dart-server.git&lt;br&gt;
    refs/heads/main:refs/heads/main 75c0e7f..b4f1198&lt;br&gt;
Done&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The log above tells us that everything was successful, but one step is missing. First, we need to declare the dynos we want for our app. For that, we need to create a &lt;code&gt;Procfile&lt;/code&gt; in the root directory of our project. Then, we enter the dyno and what it should start to execute our server. In our case, we execute the &lt;code&gt;dart_server.dart&lt;/code&gt; in the bin folder.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;:title=Procfile&lt;br&gt;
web: ./dart-sdk/bin/dart bin/dart_server.dart&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Hint: The Procfile does &lt;strong&gt;not&lt;/strong&gt; have a file extension like &lt;code&gt;.txt&lt;/code&gt; or &lt;code&gt;.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If we now &lt;code&gt;commit&lt;/code&gt; and push again to the Heroku git server we are ready to see our server in action.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&lt;br&gt;
git commit -m "Added Procfile to setup the dyno"&lt;br&gt;
git push --set-upstream heroku main&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;🎉 Great, if everything worked well, you should have now your first running Dart Server on Heroku.&lt;/p&gt;

&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;p&gt;As always, some things could go wrong, and I try to add a collection that we found out during our&lt;br&gt;
&lt;a href="https://youtu.be/3zKC4RvJOII"&gt;live stream&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dynamic Port
&lt;/h3&gt;

&lt;p&gt;Heroku does not provide you static port, so you will get a new port every time the instance is started. Especially in the free plan, that happens pretty frequently and therefore, you must take the PORT provided by the &lt;code&gt;Environment variables&lt;/code&gt; of Heroku.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`dart&lt;br&gt;
var env = Platform.environment;&lt;/p&gt;

&lt;p&gt;var port = env.entries.firstWhere((element) =&amp;gt; element.key == 'PORT',&lt;br&gt;
    orElse: () =&amp;gt; MapEntry('PORT', '8080'));&lt;/p&gt;

&lt;p&gt;var server = await shelf_io.serve(&lt;br&gt;
  logRequests().addHandler(router), '0.0.0.0', int.parse(port.value));&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Replace localhost with 0.0.0.0
&lt;/h3&gt;

&lt;p&gt;Heroku is pointing to itself while setup a server you will need to change &lt;code&gt;localhost&lt;/code&gt; to 0.0.0.0&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;dart&lt;br&gt;
var server = await shelf_io.serve(&lt;br&gt;
  logRequests().addHandler(router), '0.0.0.0', int.parse(port.value));&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;Great, we did it. With these steps, we published our server to Heroku and made our very first deployment possible. The next milestone is to create a helpful app out of this server. We were maybe starting with a small quiz app that allows you and your friends to learn more about development. For that, you will probably need more insights into the &lt;a href="https://pub.dev/packages/shelf_router"&gt;shelf_router package&lt;/a&gt; or an even bigger solution like &lt;a href="https://conduit.dev"&gt;Conduit&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Feel free to share your first examples with me on Twitter with the Hashtag &lt;code&gt;#FlutterExplained&lt;/code&gt;. I cannot wait to see your results!&lt;/p&gt;

</description>
      <category>dart</category>
      <category>heroku</category>
      <category>devops</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Code Analysis &amp; Linting in Flutter and Dart</title>
      <dc:creator>FlutterExplained</dc:creator>
      <pubDate>Mon, 04 Jan 2021 15:27:29 +0000</pubDate>
      <link>https://dev.to/myracledesign/code-analysis-linting-in-flutter-and-dart-33pb</link>
      <guid>https://dev.to/myracledesign/code-analysis-linting-in-flutter-and-dart-33pb</guid>
      <description>&lt;p&gt;One of the best practices that we introduced in the video best practices for Flutter is Flutter Code Analysis and Linting. I would like to start a small series of different Blog posts where we talk about each of these Best Practices and today we start with the very first one: Code Analysis and Linting.&lt;/p&gt;


&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--7wkZqbg9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1221361649480798210/YyQ-4eCk_normal.jpg" alt="Max Weber 💙 profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Max Weber 💙
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        @flutter_exp
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P4t6ys1m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      What is your &lt;a href="https://twitter.com/hashtag/Flutter"&gt;#Flutter&lt;/a&gt; Best Practice? 🤔
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      14:16 PM - 01 Dec 2020
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1333777067499020289" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-reply-action.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1333777067499020289" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-retweet-action.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      31
      &lt;a href="https://twitter.com/intent/like?tweet_id=1333777067499020289" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-like-action.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
      144
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;
 &lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/TBgWVqafJW4"&gt;
&lt;/iframe&gt;


&lt;h2&gt;
  
  
  Setup Code Linting for a Flutter project
&lt;/h2&gt;

&lt;p&gt;In the beginning, let me say that additional Linting in Flutter is a controversial topic. On one side, many love code linting, because it allows us to focus on crucial parts of our code. However, some people are not fond of it because it restricts them and leads to false build errors. But before we start the discussion, let us begin with what code linting is and how we can use its full potential.&lt;/p&gt;

&lt;p&gt;Code Linting is an automated verification that your code is correct. There is always a Linter that we all use in our day to day work. In editors like VSCode and Android Studio, we receive errors when our code is not runnable. The visualisation of build errors are already features of our Linter. This integrated Code Linter is a tool that checks your code for build problems, that means you would not even be possible to run your application. We do not have to search for errors in our code, and when everything is green, we are sure that our code is executable.&lt;/p&gt;

&lt;p&gt;Thanks to modern tools, we can extend these rules and check our current project for more than just broken code. For example, we can tell our Linter that we want to check for wrong code styling. In Dart and Flutter the additional lint rules are managed by a file called analysis_options.yaml. If you have never heard about a yaml file extension, it is just a convenient way to structure a file that allows you to create tree structures with two spaces. Feel free to read more about the .yaml file extension here.&lt;/p&gt;

&lt;h2&gt;
  
  
  Our Mission: Enforce single quotes in our project
&lt;/h2&gt;

&lt;p&gt;Let us assume we would force all our developers to work on our project, that every string should be done with a single quote. Our IDE should show it immediately, like in the image below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NiWFP4Ys--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9ja9203tamj7z7og13w4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NiWFP4Ys--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9ja9203tamj7z7og13w4.png" alt="Example of our result"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To achieve that the static code analyzer of Dart and Flutter recognize that mistake, we must create an analysis_options.yaml responsible for our whole project gives our Dart analyzer instructions that run in the background and verifies our code. We can create the analysis_options in the root of our project, and most IDE's like Android Studio or Visual Studio Code will right away understand what it needs to do with it. Now, let's take a closer look into the analysis_options file. Inside of the analysis_options, we can modify the behaviour of the analyzer and the linter.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Analyzer &amp;amp; Linter
&lt;/h2&gt;

&lt;p&gt;In our first section in the common analysis_options.yaml file is usually the analyzer. Here we can configure a more general part of how we want to check our code. Firstly, we can set up if we want to show errors, warnings, or as information for specific rules. Secondly, we can exclude files and folders from the checking system. Moreover, we can ignore specific rules. Last but not least, we have the chance to introduce additional strict type checking and experimental behaviour like no slow checks or super-mixins.&lt;/p&gt;

&lt;p&gt;To use now the main information that we registered to the Analyzer, we have to specify the rules that we want to apply in our project. Therefore, we use the Linter section of the analysis_options.yaml. In the linter section, we define which rules are applied to our project. There are around 180 rules that you can specify and make them right away visible in your application. To explain, all of them would bust this blog post, so feel free to look at the list of linting rules you can specify at the Linter for Dart site. &lt;/p&gt;

&lt;h2&gt;
  
  
  Linting Rules
&lt;/h2&gt;

&lt;p&gt;At the time I write this post, there are three different categories of Linting Rules. The first is the Error Rules, and they are possible coding errors. Secondly, we have the Style Rules that define code style matters, like a single quote or double quote. It does not hint whether your code is stable or not, but it helps align the whole codebase. The pub rules follow both. This set of rules defines how a pub package has to behave; it includes only two rules on how to name a package and sort dependencies in your pubspec.yaml.&lt;/p&gt;

&lt;h3&gt;
  
  
  avoid_init_to_null
&lt;/h3&gt;

&lt;p&gt;As the name already states with this linter rule, you do not allow anymore to initialize a variable with null. But why could this be helpful? In Dart, every variable that is not specified with a value is automatically set to null. There is no concept of empty memory or any other trap that we could fall into. With that in mind, a specific declaration of a variable to null would only bloat our code and is unnecessary and unneeded.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0o-bzrjv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/gzp5fvdgr36he2bpdzfa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0o-bzrjv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/gzp5fvdgr36he2bpdzfa.png" alt="Avoid Init to null"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  use_string_buffers
&lt;/h3&gt;

&lt;p&gt;Another fantastic rule that many developers are not really aware of is a more performant way to concatenate strings. The String Buffer helps you improve the concatenation of Strings and allows you to do it in the most performant way. To make sure that all contributors in your code concatenate strings efficiently, we can set the use_string_buffers style rule.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wTvnpU1u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/m02482a0dvsy2btq9bwi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wTvnpU1u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/m02482a0dvsy2btq9bwi.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4_88y6U2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9qj9t5ekjgx12ioh25nt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4_88y6U2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9qj9t5ekjgx12ioh25nt.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  prefer_double_quotes
&lt;/h3&gt;

&lt;p&gt;The prefer double quotes rule allows you to take control if you want to enforce a specific quote style. Here we prefer in our code base double quotes but also the single quote rule exists and makes it possible to enforce quote style. This is especially helpful if you work in a multilanguage team because Keyboard layouts differ from country to country. In contrast, in English and American speaking country, the single quote is easier accessible and mostly used in other countries like Germany, the double quote is usually prefered. This rule leads to clear information on how the maintainer or the owner of a package or project wants to work in general. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--utnmOoHU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/aib1tcc6d3ql1o8jacg2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--utnmOoHU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/aib1tcc6d3ql1o8jacg2.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is also the rule that we will use to finally solve our problem and enforce double quotes for the whole project.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution
&lt;/h2&gt;

&lt;p&gt;Alright now that we know how the Linter and the Analyzer work lets solve our goal for this blog post, we want to enforce every developer who works on our codebase to prefer double quotes, and if they do not, we want to really show it as an error. The first thing we have to do is to define the Analyzer with the correct severity of the issue. In our case, this would be "error". Next, we just defined in the pubspec.yaml our linter with the new rule that we want to add.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QqS1D90g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/rrw1ke4bwy8l0qdp74g7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QqS1D90g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/rrw1ke4bwy8l0qdp74g7.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now after we have specified the rule and the severity of the enforcement we can already see in our IDE the errors appearing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0IlztYOk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/cdwh64cxbzt9x9qoz790.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0IlztYOk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/cdwh64cxbzt9x9qoz790.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we now run dart analyze in our terminal inside our project, we receive a full analyzing report. Now we can use this command inside our terminal. If we use this command now in our CI / CD chain, the build will fail, and our team would have to fix it to merge it in our project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lint Rules as a package
&lt;/h2&gt;

&lt;p&gt;As always, there are fantastic packages that come with a predefined selection of rules that makes it easier to set up the first baseline that you want to use in your project. Let us first have a look at how we can include them in our project. &lt;/p&gt;

&lt;h3&gt;
  
  
  Install a third party linting rule set
&lt;/h3&gt;

&lt;p&gt;In order to add a linting rule set we have to first add the dependency to the pub.dev package in our pubspec.yaml. As an example we want to add the Lint package to our project. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--S9OqO67Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/idichxq61v2h0j9a4dpm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--S9OqO67Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/idichxq61v2h0j9a4dpm.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The next step is to import the rules from the package into our analysis_options.yaml.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ispvGlZU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/z20o8py1ulog3p1o6e2b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ispvGlZU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/z20o8py1ulog3p1o6e2b.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As soon as you open now the different files, you will now recognize that the package's linting rules are already taken into account and are ready to use. Let us assume that you do not like a rule. You can easily overwrite the behaviour by including the linter and analyzer. Your rules will overwrite the package's rules, with that you will always have control over the lining.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--J4lSvTiy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/5oh8cmpky7gwlkj8ttsz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--J4lSvTiy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/5oh8cmpky7gwlkj8ttsz.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Lint Packages
&lt;/h3&gt;

&lt;p&gt;Pascal Welsch creates the first Lint package, and it includes a baseline of lint rules for Flutter and Dart Projects. You can extend or exclude rules afterwards if you use this package, but it is created with consumers. That means if you are not necessarily working on the Flutter project. This should be your way to go.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pedantic
&lt;/h3&gt;

&lt;p&gt;The second package that I want to introduce you is the so-called pedantic package. The Flutter team created the pedantic package to support a set of rules that is usually way more restrictive in terms of usage and allowances and is a bit over-engineered from time to time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this post, we learned how to use the Linting Rules to our advantage and enforce rules so that every developer who collaborates with us works in the same way. To generate these rules and discuss them in a team could be tedious, and many people would say that it is not worth the effort. But if the conversation and discussion start now, you have the right tools to join the discussion and give some valuable insights.&lt;/p&gt;

&lt;p&gt;Thank you for reading and let me know what you are thinking about Linting rules down in the description below!&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://flutter-explained.dev/blog/flutter-analysis-linting/"&gt;Code Analysis &amp;amp; Linting in Flutter and Dart&lt;/a&gt; appeared first on &lt;a href="https://flutter-explained.dev"&gt;Flutter Explained&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>flutterframework</category>
      <category>codeanalyzer</category>
      <category>flutter</category>
      <category>learnflutter</category>
    </item>
    <item>
      <title>3. Problems we avoid with our CI / CD pipeline</title>
      <dc:creator>FlutterExplained</dc:creator>
      <pubDate>Sun, 03 May 2020 19:34:40 +0000</pubDate>
      <link>https://dev.to/myracledesign/3-problems-we-avoid-with-our-ci-cd-pipeline-mkn</link>
      <guid>https://dev.to/myracledesign/3-problems-we-avoid-with-our-ci-cd-pipeline-mkn</guid>
      <description>&lt;p&gt;In the first episode of our CI / CD blog, we worked with GitHub Actions. In our last project, we decided to work with the CI / CD solution Codemagic. We were delighted with the tool and could solve some issues in our codebase that happens to probably every development team.&lt;/p&gt;

&lt;p&gt;This article is an addition to my video for CI/CD.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/kR0N_Ecv_b0"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h1&gt;
  
  
  Save Recipe App
&lt;/h1&gt;

&lt;p&gt;Whenever we want to try a new recipe in our home, we will search on the internet and select a random recipe for cooking or baking. But as soon as we had our dinner or the cake, we can not remember and find the recipe anymore. Therefore, my partner and I decided that the world is ready for a save recipe app where we can store screenshots of all the delicious recipes that we find on the internet.&lt;/p&gt;

&lt;p&gt;The app is currently an MVP, but it has already most of the functionality that we want to deliver. This app will be today the example for our article.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uZiR2l0F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8x5yg9sh9q2x7l56rk34.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uZiR2l0F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8x5yg9sh9q2x7l56rk34.png" alt="Flutter App: Save Recipe"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We created already a Codemagic build pipeline for it. We configured it that way that whenever we push on the master branch in GitHub, it starts the build and deployment process. Feel free to check out our repository and give the project a star on GitHub.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Qmp51t0e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7qo41wtxu1o7e43q1qmi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Qmp51t0e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7qo41wtxu1o7e43q1qmi.png" alt="Codemagic Result Badge"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  CI / CD with Codemagic
&lt;/h1&gt;

&lt;p&gt;For those who never heard anything about Codemagic, I want to give a brief overview of the solution. Codemagic is a solution to create Continuous Integration (CI) and Continuous Delivery (CD) for mobile apps. It began as a pure Flutter CI / CD SaaS and is therefore strongly aligned with Flutter development. So if you or your company program in Flutter I can highly recommend you to take a look at it.&lt;/p&gt;

&lt;p&gt;Thanks to a CI / CD like Codemagic, we can run our tests and deploy without doing anything additionally as pushing to the master branch furthermore, because the pipeline runs the Analyzer, Tests and releases immediately. That creates us a safety net which helps us to avoid some common issues that happen in every team from time to time. So we want to give you a glance at what could go wrong and how you can debug this problem.&lt;/p&gt;

&lt;h1&gt;
  
  
  1. Compiler Error in our code
&lt;/h1&gt;

&lt;p&gt;Let us begin with a problem that very rarely occurs, but if it happens, it blocks a lot of team members and is usually extremely expensive. So we confine our code base with some compiler errors. We push the broken code to our branch on GitHub, and we merge it to the master branch. A new build will start to run, and a couple of minutes later, we will see the following message in our build overview.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Test run failed: Flutter analyze found issues. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The message states that the Flutter analyses did not pass, and our pipeline found issues. To receive more information, we open the testing tab and see in the results part which issues we have.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vebwa2aT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/fkwyx7wm3gldcwy8olzh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vebwa2aT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/fkwyx7wm3gldcwy8olzh.png" alt="Flutter tests result with Analyzer problems"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mMTHB3Iw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/l62ymqw1gqvl7dyyg482.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mMTHB3Iw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/l62ymqw1gqvl7dyyg482.png" alt="Flutter tests results with logs"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Flutter analyser found the mistakes that we did and shows in the logs the problematic areas. I point this “basic” error out because it helps us to find issues and protect our application from defect code. Finally, our team can be sure that after the CI / CD pipeline runs, our team does not have to fear defect code and with that a code freeze.&lt;/p&gt;

&lt;h1&gt;
  
  
  2. Broken Unit- or Integration tests
&lt;/h1&gt;

&lt;p&gt;The most natural and most widespread problem that we run into are broken unit or integration tests. When one of our tests failed, we could find the problem very easily by checking the testing part on the dashboard. The build logs are very expressive, and the result messages give us the right direction. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Test run failed: Flutter test run failed. Test run failed: Flutter test run failed. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Thanks to the dashboard, we must jump into the testing tab and see here the log and results in tabs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_9Tal_z9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/irj7zwvdv6ko4l36xeyi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_9Tal_z9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/irj7zwvdv6ko4l36xeyi.png" alt="Codemagic CI / CD Testing Tab"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qZTQMZhz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/xzl9p1t2b0akxprj09vc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qZTQMZhz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/xzl9p1t2b0akxprj09vc.png" alt="Codemagic Testing Tab Failing Test"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The result tab offers us the possibility to find the broken tests very quickly, and we can even select the test to receive the reasons from Dart Test. Another benefit is that all criteria are running through, and it does not stop at the failed test.&lt;/p&gt;

&lt;p&gt;The CI / CD helps us, in that case, to keep our code working correctly. We secure the stability of the source code. Thanks to the necessity to run all the tests, we make sure that everyone handles their changes and the inspections are the safety net for that we create them.&lt;/p&gt;

&lt;h1&gt;
  
  
  3. Wrong app-specific password
&lt;/h1&gt;

&lt;p&gt;Hurray, our app is ready to get published to the App Store, we run into issues. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Test run failed: Flutter test run failed. Test run failed: Flutter test run failed. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To get more information about our error, we open the dashboard and open the publishing part. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oC3TdI4v--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wlxxdbwqpzsga185ox07.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oC3TdI4v--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wlxxdbwqpzsga185ox07.png" alt="Failing Build - Authentication Error"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the picture above you find the following errors.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Error: Unable to validate archive “/Users/builder/ipas/Save_Recipes.tpa &lt;br&gt;
Error: code –22020 (Unable to validate your application. We are unable to create an authentications session.) &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This error messages unfortunately still do not help us what exactly went wrong. So we needed the first time the SSH access to get more details about this error. To do so, we must run the build manually and activate the “Enable Remote Access” in the specified build configuration window.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TR2dOyEh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9c22yrgg3mnhaca8o2lc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TR2dOyEh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9c22yrgg3mnhaca8o2lc.png" alt="Specify Build Configuration"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--esxV1Qp8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/0edv9b085za37lusta3d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--esxV1Qp8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/0edv9b085za37lusta3d.png" alt="Builder Remote Access"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To connect to the build machine, we need to open our Terminal and paste the statement that we get on the top of the codemagic dashboard for SSH access. After we connect to the build machine, we run in our terminal the last executed command, which you can find in the Publish area in blue.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
 

&lt;p&gt;The added verbose attribute helps us to get way more detailed information of the command and shows us additional error messages that we can use to figure out what went wrong. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rB7MigTo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/99s5lubpblwanv6abt9a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rB7MigTo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/99s5lubpblwanv6abt9a.png" alt="Specific error message after logging into SSH"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here we get the error message that the app-specific password is wrong. To solve this, we need to create an app-specific password in the app store. This password provides a secure process for a third-party app to connect with Apple Store via our Apple ID. To create this password, you can follow the steps in the apple portal.&lt;/p&gt;

&lt;p&gt;After we created our app-specific password, we head back to the configuration of our app in Codemagic. Here we have to update the app-specific password in the field iOS code signing. If you now start a new build, the problem is solved, and your build passes successfully.  &lt;/p&gt;

&lt;p&gt;The work with the SSH tool was mind-blowing. It helped us to identify the problems and solved them inside of our CI / CD tool. It showed us how vital SSH access to the running build system is if the UI cannot be expressive enough.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;I hope that these solutions for our three expensive mistakes will help you in the future to avoid these problems within your build pipeline. Thanks to the integration with Codemagic, we managed to save time, increase our stability and prevent from expensive code freezes.&lt;/p&gt;

&lt;p&gt;Please let us know in the comments below, which CI / CD tool you normally use for your projects and what problems you already solved with it.&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>codemagic</category>
      <category>cicd</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Step-by-Step guide for Flutter JSON Serialization</title>
      <dc:creator>FlutterExplained</dc:creator>
      <pubDate>Tue, 07 Apr 2020 10:58:12 +0000</pubDate>
      <link>https://dev.to/myracledesign/step-by-step-guide-for-flutter-json-serialization-40lb</link>
      <guid>https://dev.to/myracledesign/step-by-step-guide-for-flutter-json-serialization-40lb</guid>
      <description>&lt;p&gt;I published some time ago a video tutorial on how we can create a basic network request. In this post, we want to take a look at how we can improve that solution with Flutter JSON Serialization. With that, we can remove a lot of Strings in our code base.&lt;/p&gt;

&lt;p&gt;I also created a video for this article, so feel free to take a look.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/gYoQAA7rVVc"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  General Serialization
&lt;/h2&gt;

&lt;p&gt;Serialization is the process in computer science to convert an object into something that can be saved in a database or be sent via a network request. Today we want to transform a JSON String that we receive from an API and transform it into an instance of an object.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--t9b-JTmh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/f7hbtro1qxj15pkwr04l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--t9b-JTmh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/f7hbtro1qxj15pkwr04l.png" alt="Object Serialization"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wbLa7zyg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ssd40xaczu4zxqmaxvrc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wbLa7zyg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ssd40xaczu4zxqmaxvrc.png" alt="Instance Serialization"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To get our Person information as a String, I will work in the following example with the Random User Generator. This can generate random user information and provides us with an API to receive a JSON String.&lt;/p&gt;

&lt;h2&gt;
  
  
  Basic Network Request - Example App
&lt;/h2&gt;

&lt;p&gt;With the help of the &lt;a href="https://randomuser.me/"&gt;RandomUserAPI&lt;/a&gt;, I created an application that shows us a list of users as soon as we open the app. We create this Application together in the video for a &lt;a href="https://www.youtube.com/watch?v=gYoQAA7rVVc"&gt;basic network request&lt;/a&gt;. In the video, we use the manual approach for Flutter JSON Serialization, and with this blog post, we changed that to a more automated process.&lt;/p&gt;

&lt;p&gt;If you search the source code for this project and this article please you will find everything &lt;a href="https://github.com/md-weber/network_request_tutorial"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--l3hosw3S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/z2gkdq61il76amwlywg6.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--l3hosw3S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/z2gkdq61il76amwlywg6.gif" alt="List View Gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Manual Flutter JSON Serialization
&lt;/h2&gt;

&lt;p&gt;To get a better understanding of why we should prefer automatic Flutter JSON Serialization, we have to take a step backwards. For that, we first take a look at how the manual serialization works precisely.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;In the code snippet above, we created a new person object that we receive from our API. As you probably already have seen, we have to write all the key strings into the class and pollute our class with API information. Additionally, we come into the trap that if we want to add or remove an attribute, we have to change it all over.&lt;/p&gt;

&lt;p&gt;That makes the maintainability pretty hard. Especially if the API changes and we have to create it from scratch. That would lead to a lot of searches and replacements, and we will lose all IDE supports.&lt;/p&gt;

&lt;h3&gt;
  
  
  Benefits
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;No boilerplate surrounding the solution &lt;/li&gt;
&lt;li&gt;There is no setup required, so you can start directly accessing the parameters&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Disadvantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You have to write every line yourself&lt;/li&gt;
&lt;li&gt;Typos can happen and reduce the stability of your application&lt;/li&gt;
&lt;li&gt;For every new Field that you want to add, delete or modify we have to modify the code in the model&lt;/li&gt;
&lt;li&gt;Higher maintenance costs especially for larger projects or with changing API´s&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Generated Serialization
&lt;/h2&gt;

&lt;p&gt;Now that we understand the issues with self-written serialisation let's have a look at generated Flutter JSON Serialization. There is at the moment not a built-in solution in the Flutter framework, but there are plenty of perfect packages on &lt;a href="https://pub.dev"&gt;pub.dev&lt;/a&gt; for this problem. In this article, we will have a closer look at the &lt;a href="https://pub.dev/packages/json_serializable"&gt;json_serializable&lt;/a&gt; package.&lt;/p&gt;

&lt;p&gt;The package works powerfully with the build_runner package and allows us to generate the "fromJSON" and "toJSON" functions, without writing all keys of the JSON. We only have to set up our models correctly, annotate them accurately and provide two functions inside. But enough of the words, we want to see some code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dependencies
&lt;/h3&gt;

&lt;p&gt;Before we can begin to work with the json_serializable package, we have to add first some dependencies into our project.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The json_annotation is the only dependency that actually has to be inside of our project. The build_runner and json_serializable are just development dependencies and will not be part of the final bundle.&lt;/p&gt;

&lt;h3&gt;
  
  
  Modify the model
&lt;/h3&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Line 1: With the &lt;strong&gt;part 'person_model.g.dart'&lt;/strong&gt; we give the PersonModel class the possibility to access the methods inside of the person_model.g.dart file. The file will be generated later from the built_runner.&lt;/p&gt;

&lt;p&gt;Line 3: The &lt;strong&gt;@JsonSerializable()&lt;/strong&gt; annotation tells the build_runner that this class has to be concerned for the generation of a new file and creation of a serialization.&lt;/p&gt;

&lt;p&gt;Line 5 + 8: For objects inside of our JSON we have to create their representing Model classes for NameModel and PictureModel. The new models will also be annotated with &lt;strong&gt;@JsonSerializable()&lt;/strong&gt; and will also get the two new methods from line 12 and 14.&lt;/p&gt;

&lt;p&gt;Line 12: The new &lt;a href="https://dart.dev/guides/language/language-tour#factory-constructors"&gt;factory&lt;/a&gt; constructor fromJson is close to our old method. But instead of creating a new Instance of the PersonModel, we call a method &lt;strong&gt;_$PersonModelFromJson(json)&lt;/strong&gt;. This method will be generated later with the help of built_runner.&lt;/p&gt;

&lt;p&gt;Line 14: The toJson method returns as expected a Json (in Dart a Map between String and dynamic). To receive the map we call the generated function &lt;strong&gt;_$PersonModelToJson(this)&lt;/strong&gt;, and pass the current instance inside.&lt;/p&gt;

&lt;h3&gt;
  
  
  Unleash the power of the built_runner
&lt;/h3&gt;

&lt;p&gt;After we have successfully created our model with the necessary annotations and functions, we are ready to go for the built_runner script. We open our project in the terminal and execute one of the following commands.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;// Inside of Flutter projects
// Generates the generate files once
flutter pub run build_runner build

// Watches the model files and generates on each change
flutter pub run build_runner watch

// Inside of Dart projects
// Generates the generate files once
pub run build_runner build

// Watches the model files and generates on each change
pub run build_runner watch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;For the case that you have a regular dart project, I also added the commands for the consistent Dart packages creation. This command will create for you the additional *.g.dart files. These files can be inserted into .gitignore, as everyone in the team can execute this command.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JX1c9Mh1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/lsbegrsbpz0jtiz8kzli.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JX1c9Mh1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/lsbegrsbpz0jtiz8kzli.png" alt="Generated Files with the JSON Serializer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let us have a more in-depth look into the generated file from the serialisation. Here you can see the two functions that we call in the fromJson and toJson of the partial class.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Here are all the strings that we had to create beforehand inside of these methods. Thanks to built_runner they getting now generated for us. If you take a look at line 18, you can see that even the child models are generated correctly. If we now change something in our class and execute once more the build runner (or let it watch), then we will see how it gets added to the list automatically.&lt;/p&gt;

&lt;h3&gt;
  
  
  Benefits
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Modifications to the class are instantaneously reflected&lt;/li&gt;
&lt;li&gt;Lower maintenance due to less written code&lt;/li&gt;
&lt;li&gt;Types are directly set via the attributes&lt;/li&gt;
&lt;li&gt;No magic happens, the generated files are in the project&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Disadvantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Initial setup is increased &lt;/li&gt;
&lt;li&gt;There is some boilerplate involved&lt;/li&gt;
&lt;li&gt;You have to make sure everyone on the team is aware of the build_runner function (possible solution would be a script or a good readme.md file)&lt;/li&gt;
&lt;li&gt;Generated files could distract from the real model files&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Packages for Flutter JSON Serialization
&lt;/h2&gt;

&lt;p&gt;There are several other packages that you can use for generated JSON Serialization.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pub.dev/packages/built_value"&gt;built_value&lt;/a&gt; &lt;a href="https://pub.dev/packages/built_collection"&gt;built_collection&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The built_value or built_collection can handle JSON Serialization in a very similar way as we did in json_serializable. But add beneficial functions like immutability, comparability and other quality of life functions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pub.dev/packages/dart_json"&gt;dart_json&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The dart_json has the benefit that it is absolutely dependency less. If you search for a solution with as few dependencies as possible this package is your best bet.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://app.quicktype.io?share=Dxzba5UONSYqWKLpCbog"&gt;JSON Web parser&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;There is some JSON Web parser that creates out of your JSON a valid dart model for you. You can copy a JSON into the left side and copy the model on the right side into your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;JSON Serialization is a crucial topic, primarily if you work with a lot of external requests and different API´s that are changing their contracts from time to time. These should lead to more productivity so that we can implement significant features easier.&lt;/p&gt;

&lt;p&gt;I made a poll on twitter to see which framework is the most used at the moment, but it seems it is pretty close together. My recommendation is to take a look at each package/solution and then use which one fits your needs best.&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>development</category>
      <category>serialization</category>
      <category>json</category>
    </item>
    <item>
      <title>Setup a Flutter Web Project on GitHub Pages</title>
      <dc:creator>FlutterExplained</dc:creator>
      <pubDate>Thu, 13 Feb 2020 14:01:24 +0000</pubDate>
      <link>https://dev.to/myracledesign/setup-a-flutter-web-project-on-github-pages-3eka</link>
      <guid>https://dev.to/myracledesign/setup-a-flutter-web-project-on-github-pages-3eka</guid>
      <description>&lt;p&gt;After my last &lt;a href="https://dev.to/myracledesign/my-flutter-journey-3ndj"&gt;blog entry&lt;/a&gt;, I got asked how I created a web project in Flutter and how I managed to deploy it. So join me on the journey how to create a Flutter web app and implement the whole thing on GitHub Pages.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/54SM24tLlhc"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Flutter Channels
&lt;/h2&gt;

&lt;p&gt;To enable flutter web, you have to set up your Flutter CLI properly, and after that, you have to make sure you are on the right channel. Today when I write this post, Flutter web is still in beta, so we have to select a branch that supports beta features.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; flutter channel
Flutter channels:
&lt;span class="k"&gt;*&lt;/span&gt;  master   
   dev
&lt;span class="k"&gt;*&lt;/span&gt;  beta   
   stable
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The master channel is the current tip of development. It contains the newest changes in the framework, but it is also vulnerable to breaking changes. So that means in the worst case, something is going wrong. The beta channel is a code selection of the flutter team once a month to a branch that contains the newest released features. It is selected and more stable. So if you want to try around, this would be the channel to go.&lt;/p&gt;

&lt;p&gt;For more information about the channels in Flutter, take a look &lt;a href="https://github.com/flutter/flutter/wiki/Flutter-build-release-channels" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; flutter channel beta
&lt;span class="c"&gt;# To download the Flutter SDK execute flutter doctor&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; flutter doctor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Enable Flutter Web
&lt;/h2&gt;

&lt;p&gt;After we set the correct channel and downloaded the new version of flutter, we have to enable the web development model.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; flutter config &lt;span class="nt"&gt;--enable-web&lt;/span&gt;
Setting 
   &lt;span class="s2"&gt;"enable-web"&lt;/span&gt; value to &lt;span class="s2"&gt;"true"&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; flutter config Settings:  enable-web: &lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we are ready to go. Next, we have to create a basic Flutter project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; flutter create ./project-name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Flutter create will create all the relevant folders for us. If we open up that project, we should see now the folder "web" inside of the project. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3ac9a3cqtopoiiu49wlk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3ac9a3cqtopoiiu49wlk.png" alt="Folder Structure"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The last step is to run the app. So go into the project folder and run flutter devices. We should see now chrome and Web Server as a choice.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;cd&lt;/span&gt; ./project-name
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; flutter devices
Chrome     • chrome     • web-javascript • Google Chrome 80.0.3987.87
Web Server • web-server • web-javascript • Flutter Tools

&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; flutter run &lt;span class="nt"&gt;-d&lt;/span&gt; chrome
&lt;span class="c"&gt;# Should startup your web dev server.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After the flutter run -d chrome command, the chrome browser will start up and reveal the Flutter app.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgoctx0y0q1rj33zx75p1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgoctx0y0q1rj33zx75p1.png" alt="Basic Flutter App in Browser"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Perfect, we did it!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/wrzf9P70YWLJK/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/wrzf9P70YWLJK/giphy.gif" alt="We did it"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploy on GitHub
&lt;/h2&gt;

&lt;p&gt;Before we can deploy, we have to create a new repository in GitHub and to use it as GitHub pages, it needs to have a specific naming convention.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Template: :: GitHub-UserName ::.github.io&lt;br&gt;
Example: &lt;a href="https://github.com/md-weber/md-weber.github.io" rel="noopener noreferrer"&gt;md-weber.github.io&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now we can create anything that we want in our Flutter app. If we are ready to go, we have to build the app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; flutter build web &lt;span class="nt"&gt;--releaseCompiling&lt;/span&gt; 
lib/main.dart &lt;span class="k"&gt;for &lt;/span&gt;the Web...                              1.6s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, your project will contain a build/web folder. This folder contains all the files that you will need to upload to your GitHub Repository. Open a terminal and switch to the folder and push it into your repository.&lt;/p&gt;

&lt;p&gt;If you are new to GitHub and Git, this &lt;a href="https://product.hubspot.com/blog/git-and-github-tutorial-for-beginners" rel="noopener noreferrer"&gt;Guide&lt;/a&gt; could help you.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;cd&lt;/span&gt; ./build/web

&lt;span class="c"&gt;# The following are the steps that I took. They could vary from project to project. &lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; git init
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; git remote add origin 
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; git add &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Init Flutter web project"&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; git push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After the push, GitHub will take care of the rest. It immediately creates for you an environment and pushes your changes to the website. &lt;/p&gt;

&lt;p&gt;Inside of your GitHub repository, you will find a new Tab called environments. In this tab, you can see how far your deployment process is. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fl1qvuyuvqdksqeeeukvw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fl1qvuyuvqdksqeeeukvw.png" alt="GitHub environment"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now you can navigate to  https://::username::.github.io or my example &lt;a href="https://md-weber.github.io/" rel="noopener noreferrer"&gt;https://md-weber.github.io/&lt;/a&gt; to see your webpage.&lt;/p&gt;

&lt;p&gt;If you get at that stage a 404 error, please try to add the /index.html to your path and now you should see your very first Flutter Web App.&lt;/p&gt;

&lt;p&gt;Thank you for reading!&lt;/p&gt;

</description>
      <category>dart</category>
      <category>flutter</category>
      <category>github</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>My Flutter Journey</title>
      <dc:creator>FlutterExplained</dc:creator>
      <pubDate>Mon, 10 Feb 2020 13:06:51 +0000</pubDate>
      <link>https://dev.to/myracledesign/my-flutter-journey-3ndj</link>
      <guid>https://dev.to/myracledesign/my-flutter-journey-3ndj</guid>
      <description>&lt;p&gt;Frankly, the first time I heard about flutter was at the Google I/O 2019. For me, who always enjoyed working with Hot Reload and hated the way how Xamarin works for mobile apps. I was searching for a hybrid programming pattern for both android and iOS devices. Even though React Native was already out, it has the same foundation. JavaScript, this is not necessarily bad, but it has its own downsides. &lt;/p&gt;

&lt;p&gt;I searched for a strongly typed language that shows me errors before I am falling for them. Now after one and a half year I can say that I transformed from an Angular 2+ engineer to a flutter engineer and I even started my own Youtube Channel with the topic FlutterExplained.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/iHIhnALkFj0"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h1&gt;
  
  
  First steps
&lt;/h1&gt;

&lt;p&gt;I started by creating some smaller prototypes. Without knowing the Dart Language, I wanted to create my first web app, which I did with the help of &lt;a href="https://dev.to/chingu"&gt;Chingu&lt;/a&gt;. Chingu is a platform where you collaborate with other members of a community to create a new project.&lt;/p&gt;

&lt;p&gt;The first time I used Flutter I used it in a Web Project and developed the backend with &lt;a href="https://aqueduct.io/"&gt;Aqueduct&lt;/a&gt;. Aqueduct is a framework in Dart, with that you are able to create a scalable backend. That was a fantastic time, learning Heroku added some CI/CD with Github Actions and was able in two weeks to create a &lt;a href="https://digital-journal-client.herokuapp.com"&gt;web journal&lt;/a&gt; full out of Flutter.&lt;/p&gt;

&lt;p&gt;It was far from perfect but jeez I was so proud of it. I wrote articles and showed it in the community, and they liked it very much. That gave me the drive to work harder on my Flutter skills. At the end of 2019, I finally quitted my Freelance contract and started working full time on Flutter.&lt;/p&gt;

&lt;h1&gt;
  
  
  Starting with my Flutter Journey
&lt;/h1&gt;

&lt;p&gt;I wanted to enhance my Flutter knowledge, I completed a certificate on Udemy from the "&lt;a href="https://www.udemy.com/course/flutter-bootcamp-with-dart/"&gt;The Complete 2020 Flutter Development Bootcamp with Dart&lt;/a&gt;". I was glad that I have done it, just to see all things once more together and understand more of the core concepts.&lt;/p&gt;

&lt;p&gt;After that, I tried to replenish my social media channels. My &lt;a href="https://twitter.com/max_myracle"&gt;Twitter&lt;/a&gt; activity was not existent and my old &lt;a href="https://www.youtube.com/channel/UCgUnLn1FpuHHmO66vn4o1NA"&gt;youtube channel&lt;/a&gt; with around 20 subscribers was not worth a lot. Additionally, I had some ideas in my mind that I wanted to realise. Creating a world travel companion and even an electric calculator (which is currently in Alpha). That was the start of my journey.&lt;/p&gt;

&lt;p&gt;First, I developed the electrical calculator to see if I can manage to create an app in one week, and well thanks to Flutter I did! There are some improvements that I have to do, but it will be released in the next weeks. Also, I started with my youtube channel and got till now 400 views on a "MediaQuery and LayoutBuilder" Video, which I used to create a better user experience in my app.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/7kn27lnYSAE9O/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/7kn27lnYSAE9O/giphy.gif" alt="Media"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;via &lt;a href="https://giphy.com/gifs/running-muppets-7kn27lnYSAE9O/media"&gt;Giphy&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is super exciting and I am thrilled that it works like that. This motivates me to improve myself even further so that I can explain everyone, even better the pros and cons of Dart and Flutter Development.&lt;/p&gt;

&lt;h1&gt;
  
  
  Advantages
&lt;/h1&gt;

&lt;p&gt;I have never learned that much in such a short amount of time. Also for the videos that I prepare, I have to continually improve myself. Learning to cut videos, add effects, creating better boilerplates, learning flutter details and dart packages. Additionally, my partner and me are working to setup up our own startup which takes time to prepare pitches and talk to investors.&lt;/p&gt;

&lt;p&gt;My &lt;a href="https://github.com/md-weber?tab=overview&amp;amp;from=2020-02-01&amp;amp;to=2020-02-10"&gt;Github&lt;/a&gt; Repository explodes thanks to all the commits and if you compare it to 2014 when I draw little pictures in my timeline, it is a dramatic increase.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--17HFFFQv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/gjgicd2mxvzb6l4cdiu3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--17HFFFQv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/gjgicd2mxvzb6l4cdiu3.png" alt="Github Changes 2014"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0EdfMif2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ssag831ymsx9ivwiyn5o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0EdfMif2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ssag831ymsx9ivwiyn5o.png" alt="Github Changes 2020"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Furthermore, I found a way into the flutter community and had the opportunity to talk with people who have the same interest as me. To be part of this new and interactive community is just amazing and the people encourage you to be a better developer in every aspect.&lt;/p&gt;

&lt;h1&gt;
  
  
  Downsides
&lt;/h1&gt;

&lt;p&gt;Currently, I am living from my hard work of last year, and there are less till no projects for Flutter Development in Germany. So my clear goal to earn money with Flutter is to create my own products, services and apps. Also, my &lt;a href="https://www.youtube.com/channel/UCgUnLn1FpuHHmO66vn4o1NA"&gt;Youtube&lt;/a&gt; Channel is one of my critical hopes for income. But there are a lot of barriers and if you think you can earn money with &lt;a href="https://www.buymeacoffee.com/MyracleDesign"&gt;BuyMeACoffee&lt;/a&gt; ... well, think again. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/3o6UB5RrlQuMfZp82Y/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/3o6UB5RrlQuMfZp82Y/giphy.gif" alt="Empty pockets"&gt;&lt;/a&gt;&lt;br&gt;
via &lt;a href="https://giphy.com/gifs/confused-travolta-poor-wallet-3o6UB5RrlQuMfZp82Y/media"&gt;Giphy&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Future perspective and Goals for 2020
&lt;/h1&gt;

&lt;p&gt;I still have to learn a lot about BloC pattern, state management and advanced API handling with built_value and built_collection, but that does not keep me away from working further with this great technology. &lt;/p&gt;

&lt;p&gt;I would say there was never a technology stack that cared so much about the needs and desires of their developers. The users love the material design and flexibility. Designers see their creation coming alive in no time. The community seems to be still small but is one of the best groups  I have ever worked with. All these things combined make me love Flutter.&lt;/p&gt;

&lt;p&gt;My goal for this year is to earn a living from Flutter development. The dream would be to go full time on youtube and earn my money as a flutter tutor and speaker. Additionally, I want to publish at least two apps this year.&lt;/p&gt;

&lt;p&gt;Thank you for reading so far, please feel free to share your journey with us. I would love to hear more about it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/MyracleDesign"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zQj764Ae--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.buymeacoffee.com/buttons/default-orange.png" alt="Buy Me A Coffee"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>tutorial</category>
      <category>motivation</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
