<?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: Ibtesam Ansari</title>
    <description>The latest articles on DEV Community by Ibtesam Ansari (@ibtesam123).</description>
    <link>https://dev.to/ibtesam123</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%2F449134%2Ffaf271f8-4102-4cd5-892a-00406edfed29.jpeg</url>
      <title>DEV Community: Ibtesam Ansari</title>
      <link>https://dev.to/ibtesam123</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ibtesam123"/>
    <language>en</language>
    <item>
      <title>Realtime Chat App - Flutter, Node.js &amp; Socket.io</title>
      <dc:creator>Ibtesam Ansari</dc:creator>
      <pubDate>Fri, 28 Aug 2020 17:14:40 +0000</pubDate>
      <link>https://dev.to/ibtesam123/realtime-chat-app-flutter-node-js-socket-io-em7</link>
      <guid>https://dev.to/ibtesam123/realtime-chat-app-flutter-node-js-socket-io-em7</guid>
      <description>&lt;p&gt;In this blog, we will see how to make a realtime chat app using Node.js as the backend and Flutter as the frontend. We will use sockets to communicate between devices.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;br&gt;
The following should be installed and running in your PC.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Node.js : &lt;a href="https://nodejs.org/en/download/" rel="noopener noreferrer"&gt;https://nodejs.org/en/download/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Flutter : &lt;a href="https://flutter.dev/docs/get-started/install" rel="noopener noreferrer"&gt;https://flutter.dev/docs/get-started/install&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Heroku CLI : &lt;a href="https://devcenter.heroku.com/articles/heroku-cli" rel="noopener noreferrer"&gt;https://devcenter.heroku.com/articles/heroku-cli&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;git : &lt;a href="https://git-scm.com/downloads" rel="noopener noreferrer"&gt;https://git-scm.com/downloads&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;
  
  
  Nodejs (Server-Side)
&lt;/h1&gt;

&lt;p&gt;Create a folder named &lt;strong&gt;&lt;em&gt;real_chat_node&lt;/em&gt;&lt;/strong&gt; and open it in the terminal. Then run the following command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm init&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Accept the defaults by pressing Enter. Next install the required packages through &lt;strong&gt;&lt;em&gt;npm&lt;/em&gt;&lt;/strong&gt;, which is available by default when you install node.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install express nodemon http socket.io&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Open the folder with your favourite IDE. Then go to &lt;strong&gt;&lt;em&gt;package.json&lt;/em&gt;&lt;/strong&gt; and in scripts add a &lt;strong&gt;&lt;em&gt;dev&lt;/em&gt;&lt;/strong&gt; key.&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%2Fmiro.medium.com%2Fmax%2F463%2F1%2A7nzwOQP5pYeRYuhpY3m7hQ.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%2Fmiro.medium.com%2Fmax%2F463%2F1%2A7nzwOQP5pYeRYuhpY3m7hQ.png" alt="package.json"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next create a &lt;strong&gt;&lt;em&gt;index.js&lt;/em&gt;&lt;/strong&gt; file in your root directory. Write the following code in it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const app = require('express')()
const http = require('http').createServer(app)
app.get('/', (req, res) =&amp;gt; {
   res.send("Node Server is running. Yay!!")
})
http.listen(8080)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;On your terminal type the following command:&lt;br&gt;
&lt;code&gt;npm run dev&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Leave it running and go to &lt;strong&gt;&lt;em&gt;&lt;a href="http://localhost:8080" rel="noopener noreferrer"&gt;http://localhost:8080&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt; and you will get the message.&lt;/p&gt;

&lt;p&gt;Now lets add socket in our nodejs app.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const app = require('express')()
const http = require('http').createServer(app)


app.get('/', (req, res) =&amp;gt; {
    res.send("Node Server is running. Yay!!")
})

//Socket Logic
const socketio = require('socket.io')(http)

socketio.on("connection", (userSocket) =&amp;gt; {
    userSocket.on("send_message", (data) =&amp;gt; {
        userSocket.broadcast.emit("receive_message", data)
    })
})

http.listen(process.env.PORT)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The &lt;strong&gt;&lt;em&gt;connection&lt;/em&gt;&lt;/strong&gt; event is triggered whenever a socket is connected to our app. We then add a listener to the &lt;strong&gt;&lt;em&gt;send_message&lt;/em&gt;&lt;/strong&gt; event which forwards any data that is sent to it to &lt;strong&gt;&lt;em&gt;receive_message&lt;/em&gt;&lt;/strong&gt; event.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Voila!! Our backend is ready. Let’s deploy it to heroku and then we can start our Flutter app.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Quick Note: The following are the ways to send and listen on events.&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F360%2F1%2AfNrtU4TpdWFwyXOxzPlFNQ.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%2Fmiro.medium.com%2Fmax%2F360%2F1%2AfNrtU4TpdWFwyXOxzPlFNQ.png" alt="send listen socket"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Heroku (Deployment)
&lt;/h1&gt;

&lt;p&gt;Heroku is a cloud platform which will deploy our app so that we can access it from anywhere though a url. Let’s get started.&lt;/p&gt;

&lt;p&gt;Before we deploy our app, we just need to make few changes.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;In index.js file replace port 8080 with process.env.PORT.&lt;br&gt;
&lt;code&gt;http.listen(process.env.PORT)&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a file named &lt;strong&gt;&lt;em&gt;Procfile&lt;/em&gt;&lt;/strong&gt; in the root directory and write the following in it.&lt;br&gt;
&lt;code&gt;web: node index.js&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Also create a &lt;strong&gt;&lt;em&gt;.gitignore&lt;/em&gt;&lt;/strong&gt; file and add the folowing&lt;br&gt;
&lt;code&gt;/node_modules&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&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%2Fmiro.medium.com%2Fmax%2F700%2F1%2AssgP-pRF8Uq6bUB09MroJA.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%2Fmiro.medium.com%2Fmax%2F700%2F1%2AssgP-pRF8Uq6bUB09MroJA.png" alt="deploy"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Next open the root directory in your terminal and setup heroku cli&lt;br&gt;
&lt;code&gt;heroku login&lt;/code&gt;&lt;br&gt;
You will be asked to login in. Enter your credentials and you are good to go.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now create your heroku app. &lt;code&gt;heroku create &amp;lt;your-app-name-here&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now initialize git and commit everything to heroku master.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git init
git add .
git commit -m "Initial Commit"
git push heroku master
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Wait for it to finish and done. You can go to the url generated to see the same message as earlier.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: Use your own url that will be generated.&lt;/em&gt;&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%2Fmiro.medium.com%2Fmax%2F511%2F1%2Afnq9gxWN5dCw2hNW5ZOWZQ.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%2Fmiro.medium.com%2Fmax%2F511%2F1%2Afnq9gxWN5dCw2hNW5ZOWZQ.png" alt="deploy done"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Flutter (Client-Side)
&lt;/h1&gt;

&lt;p&gt;So our backend part is complete and now its time to start making our chat app in Flutter.&lt;/p&gt;

&lt;p&gt;Open your terminal and type in the following command to create our flutter app.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;flutter create --androidx real_chat_flutter&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;After the project is created open the folder in your IDE.&lt;/p&gt;

&lt;p&gt;In your &lt;strong&gt;&lt;em&gt;pubspec.yaml&lt;/em&gt;&lt;/strong&gt; file add the following dependency&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dependencies:
  flutter:
    sdk: flutter
  cupertino_icons: ^0.1.2
  flutter_socket_io: ^0.6.0  //Add this dependency
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Open the &lt;strong&gt;&lt;em&gt;main.dart&lt;/em&gt;&lt;/strong&gt; in the lib folder and delete all the code and add the following code:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import 'package:flutter/material.dart';
import './ChatPage.dart';

void main() =&amp;gt; runApp(MyMaterial());

class MyMaterial extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: ChatPage(),
    );
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now we have to create the ChatPage. Create &lt;strong&gt;&lt;em&gt;ChatPage.dart&lt;/em&gt;&lt;/strong&gt; file inside lib folder. Lets write the code for our Chat Page.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:flutter_socket_io/flutter_socket_io.dart';
import 'package:flutter_socket_io/socket_io_manager.dart';

class ChatPage extends StatefulWidget {
  @override
  _ChatPageState createState() =&amp;gt; _ChatPageState();
}

class _ChatPageState extends State&amp;lt;ChatPage&amp;gt; {
  SocketIO socketIO;
  List&amp;lt;String&amp;gt; messages;
  double height, width;
  TextEditingController textController;
  ScrollController scrollController;

  @override
  void initState() {
    //Initializing the message list
    messages = List&amp;lt;String&amp;gt;();
    //Initializing the TextEditingController and ScrollController
    textController = TextEditingController();
    scrollController = ScrollController();
    //Creating the socket
    socketIO = SocketIOManager().createSocketIO(
      '&amp;lt;ENTER THE URL OF YOUR DEPLOYED APP&amp;gt;',
      '/',
    );
    //Call init before doing anything with socket
    socketIO.init();
    //Subscribe to an event to listen to
    socketIO.subscribe('receive_message', (jsonData) {
      //Convert the JSON data received into a Map
      Map&amp;lt;String, dynamic&amp;gt; data = json.decode(jsonData);
      this.setState(() =&amp;gt; messages.add(data['message']));
      scrollController.animateTo(
        scrollController.position.maxScrollExtent,
        duration: Duration(milliseconds: 600),
        curve: Curves.ease,
      );
    });
    //Connect to the socket
    socketIO.connect();
    super.initState();
  }

  Widget buildSingleMessage(int index) {
    return Container(
      alignment: Alignment.centerLeft,
      child: Container(
        padding: const EdgeInsets.all(20.0),
        margin: const EdgeInsets.only(bottom: 20.0, left: 20.0),
        decoration: BoxDecoration(
          color: Colors.deepPurple,
          borderRadius: BorderRadius.circular(20.0),
        ),
        child: Text(
          messages[index],
          style: TextStyle(color: Colors.white, fontSize: 15.0),
        ),
      ),
    );
  }

  Widget buildMessageList() {
    return Container(
      height: height * 0.8,
      width: width,
      child: ListView.builder(
        controller: scrollController,
        itemCount: messages.length,
        itemBuilder: (BuildContext context, int index) {
          return buildSingleMessage(index);
        },
      ),
    );
  }

  Widget buildChatInput() {
    return Container(
      width: width * 0.7,
      padding: const EdgeInsets.all(2.0),
      margin: const EdgeInsets.only(left: 40.0),
      child: TextField(
        decoration: InputDecoration.collapsed(
          hintText: 'Send a message...',
        ),
        controller: textController,
      ),
    );
  }

  Widget buildSendButton() {
    return FloatingActionButton(
      backgroundColor: Colors.deepPurple,
      onPressed: () {
        //Check if the textfield has text or not
        if (textController.text.isNotEmpty) {
          //Send the message as JSON data to send_message event
          socketIO.sendMessage(
              'send_message', json.encode({'message': textController.text}));
          //Add the message to the list
          this.setState(() =&amp;gt; messages.add(textController.text));
          textController.text = '';
          //Scrolldown the list to show the latest message
          scrollController.animateTo(
            scrollController.position.maxScrollExtent,
            duration: Duration(milliseconds: 600),
            curve: Curves.ease,
          );
        }
      },
      child: Icon(
        Icons.send,
        size: 30,
      ),
    );
  }

  Widget buildInputArea() {
    return Container(
      height: height * 0.1,
      width: width,
      child: Row(
        children: &amp;lt;Widget&amp;gt;[
          buildChatInput(),
          buildSendButton(),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    height = MediaQuery.of(context).size.height;
    width = MediaQuery.of(context).size.width;
    return Scaffold(
      body: SingleChildScrollView(
        child: Column(
          children: &amp;lt;Widget&amp;gt;[
            SizedBox(height: height * 0.1),
            buildMessageList(),
            buildInputArea(),
          ],
        ),
      ),
    );
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now run the app in two devices and chat back and forth 😄.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;If you face any problem, you can check out my github repo :&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&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%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/ibtesam123" rel="noopener noreferrer"&gt;
        ibtesam123
      &lt;/a&gt; / &lt;a href="https://github.com/ibtesam123/real_chat_node" rel="noopener noreferrer"&gt;
        real_chat_node
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;




&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&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%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/ibtesam123" rel="noopener noreferrer"&gt;
        ibtesam123
      &lt;/a&gt; / &lt;a href="https://github.com/ibtesam123/real_chat_flutter" rel="noopener noreferrer"&gt;
        real_chat_flutter
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Don’t forget to star ⭐ the repo and give claps 👏 if you liked the article. If you have any queries you can ask in comments. Thank you 😄&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>dart</category>
      <category>node</category>
      <category>socketio</category>
    </item>
  </channel>
</rss>
