<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ messaging - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ messaging - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sun, 14 Jun 2026 17:08:05 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/messaging/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Pub/Sub in Redis – How to Use the Publish/Subscribe Messaging Pattern ]]>
                </title>
                <description>
                    <![CDATA[ When you're working on an application that needs to be easily maintainable, scalable, and performant, the Publish/Subscribe messaging pattern is a good choice. The idea behind it is simple, but powerful. We have senders called publishers. Their sole ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-pub-sub-in-redis/</link>
                <guid isPermaLink="false">66d460569f2bec37e2da0654</guid>
                
                    <category>
                        <![CDATA[ messaging ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Redis ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Mihail Gaberov ]]>
                </dc:creator>
                <pubDate>Fri, 28 Apr 2023 14:33:25 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/04/image-332-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>When you're working on an application that needs to be easily maintainable, scalable, and performant, the Publish/Subscribe messaging pattern is a good choice.</p>
<p>The idea behind it is simple, but powerful. We have senders called <em>publishers.</em> Their sole role is to send or <em>publish</em> messages. They don’t care about who is going to receive them or if someone will receive them at all. They just shoot and forget the messages. And they do that via <em>channels</em>.</p>
<p>Think of them as, for example, TV channels. We have Sports channels, Weather Forecasting channels, Cooking channels, and so on. Every publisher sends its messages to a certain channel, and whoever is <em>subscribed</em> for this channel will be able to receive these messages.</p>
<p>Here is where the <em>subscribers</em> come in play. They can subscribe to one or more channels and start receiving the messages broadcasted in there.</p>
<p>As we already mentioned, the messages are to be sent and forgotten. This means that if a subscriber subscribes for a certain channel, all the messages that were sent previously in that channel are not going to be available to this subscriber.</p>
<p>Due to the nature of this kind of architecture, we can easily achieve low coupling between the different components and provide a solid foundation for building robust and easy-to-maintain applications.</p>
<p>For example, imagine a situation where we need to replace or improve the publishing part of our system – say add more publishers, more channels or so on. Since the two parts are isolated, meaning publishers don’t care about subscribers and vice versa, we could easily do that without worrying whether we are breaking some other part of the system. We just add the new publishers. Then later, when a subscriber comes to the relevant channels, it just starts using them.</p>
<h2 id="heading-what-is-redis">What is Redis?</h2>
<p>The initial idea behind Redis was to serve as an in-memory cache solution, as an alternative to its ancestor <a target="_blank" href="https://www.memcached.org/">Memcached</a>.</p>
<p>But nowadays it's a many-in-one solution, providing an in-memory data structure store, key-value database, message brokering, and so on. This makes it perfect candidate when building an application that needs a really fast caching solution as well as some of the other features mentioned before. Especially if the performance of the app is crucial for its regular usage.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/04/image-333.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Redis performance comparison (source: google)</em></p>
<p>One of the biggest advantages when using Redis is the huge community and technical resources you can find online. A lot of these resources are free, and there are online platforms that have free tier offerings.</p>
<p>Redis includes in its arsenal a cloud solution as well. If you want to try it yourself, you may go <a target="_blank" href="https://redis.com/try-free/">here</a> and register a free account or use their initial coupon offering.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/04/image-334.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Redis Enterprise Cloud Sign Up / Sign In page</em></p>
<h2 id="heading-pubsub-in-redis">Pub/Sub in Redis</h2>
<h3 id="heading-what-is-pubsub">What is pub/sub?</h3>
<p><a target="_blank" href="https://redis.io/docs/manual/pubsub/">Publish/Subscribe channels in Redis</a> is one of the features I haven’t mentioned above but it’s included in the last versions of Redis. This is their implementation of the <a target="_blank" href="https://redis.io/docs/manual/pubsub/">pub/sub messaging pattern</a>, where we have publishers and subscribers that exchange messages via channels.</p>
<p>We'll go briefly through it below and then see it in practice in a <a target="_blank" href="https://github.com/mihailgaberov/redis-pub-sub-visualized">small demo app</a> I have prepared for you.</p>
<h3 id="heading-how-does-redis-pubsub-work">How does Redis pub/sub work?</h3>
<p>We have publishers (the producers of messages), channels (that the messages are going through), and subscribers (the receivers of the messages). Who receives what depends solely on who is subscribed to which channel.</p>
<p><strong>Let's see how this works in an example:</strong></p>
<p>If we have created three publishers which will be publishing messages to three different channels. Let’s call them channels 1, 2 and 3. We also have three subscribers, let’s call them subscribers A, B and C.</p>
<p>Now, let’s imagine subscriber A is listening for messages on all three channels, that is, it's subscribed to them. And subscribers B and C are subscribed to channels 2 and 3. This means that when either of the three publishers sends a message, subscriber A will receive it. And subscribers B and C will be receiving messages sent only by publishers 2 and 3, because they are listening only for messages on these channels (2 and 3).</p>
<p>Notice that we have two entities using a channel – one is sending, the other is receiving – but they are totally independent. And the messages being sent are not persisted. Once they are sent by the publisher they are forgotten. The only entities that are subscribed at the moment of sending will get them.</p>
<h3 id="heading-how-to-use-pubsub-in-redis">How to use pub/sub in Redis</h3>
<p>There are a plethora of client libraries that you can use with Redis. There is a <a target="_blank" href="https://redis.io/docs/clients/">dedicated page</a> where everybody can go and pick one, depending on the specific project needs or just on your preferred programming language.</p>
<p>People at Redis also marked some of these repositories as <em>recommended</em> which makes the choice easier, if you are new to all this.</p>
<p>For our demo below, I used <a target="_blank" href="https://github.com/luin/ioredis">ioredis</a>, a full-featured Redis client for Node.js. I chose this because the demo app UI is built with React and Node.js and my server code goes pretty well with it.</p>
<h2 id="heading-redis-pubsub-demo">Redis Pub/Sub Demo</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/04/image-336.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Redis Pub/Sub Visualizer app</em></p>
<p>Show time!</p>
<p>The idea behind the <a target="_blank" href="https://github.com/mihailgaberov/redis-pub-sub-visualized">demo application</a> is to show visually how the pattern works.</p>
<p>What you will see when you open it for first the time is three buttons for publishing simple messages (news) in the three imaginary TV channels: Weather, Sports and Music.</p>
<p>The cards below the publish buttons are the subscribers. Once you move your mouse cursor over any of them, it will flip to its back side and you will see three buttons. You may use each of these buttons to subscribe to the relevant channel.</p>
<p>Once a subscriber is signed over a channel and you click on the icon or the publish button for this channel, you will see a sample news appearing on the front side of the card.</p>
<p>Play with different publishers/subscribers combinations and see the result.</p>
<p>I hope this will give you a better understanding of what I explained in the example above.</p>
<h3 id="heading-how-to-run-the-demo-app-locally"><strong>How to run the demo app locally</strong></h3>
<p>In order to install and run the demo application locally, follow the steps below (all commands are considered to be run from the root project directory):</p>
<p><strong>Run frontend:</strong></p>
<p><code>cd client yarn &amp;&amp; yarn dev</code></p>
<p><strong>Run backend:</strong></p>
<p><code>cd server &amp;&amp; yarn yarn start</code></p>
<p>And finally, use your local installation of Docker (if don’t have one, you may get it from <a target="_blank" href="https://docs.docker.com/get-docker/">here</a>) to run this:</p>
<pre><code class="lang-python">docker run -p <span class="hljs-number">6379</span>:<span class="hljs-number">6379</span> redislabs/redismod:preview
</code></pre>
<p>That’s probably the easiest way to have a running copy of Redis locally. The other option would be to use <a target="_blank" href="https://redis.com/try-free/">Redis Cloud</a> directly and deploy the application online. This is an option I am still investigating and if I manage to do it, I will deploy the whole app and will let you know.</p>
<h2 id="heading-closing">Closing</h2>
<p>This article introduced you to the pub/sub messaging pattern subject. It's important to remember that whenever we want to build a highly performant application with a low coupled architecture and real-time like messaging features, consider using the Publish/Subscribe pattern and Redis in particular.</p>
<p>In fact a lot of the real life applications that use Redis are dashboard-based. This means that usually there is a nice dashboard screen, showing different data, often being updated in real time.</p>
<p>Imagine, for example, a system showing traffic in a specific area. This kind of software is a perfect candidate for leveraging the advantages of pub/sub. And in many cases this is achieved by using Redis.</p>
<p>In any case, as developers and engineers, we should always be guided by the specific needs of the project we are working on. Whenever we decide to introduce a new pattern or technology, we should do it carefully and back it up with serious research.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ RTC Connecting Discord – How to Fix the Server Error ]]>
                </title>
                <description>
                    <![CDATA[ Discord is an instant messaging app that lets you communicate through voice, video, and texts. It is available in a web-based form, a desktop app, and a mobile app. But sometimes, when you're trying to establish a voice call connection, you'll get an... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/rtc-connecting-discord-how-to-fix-the-server-error/</link>
                <guid isPermaLink="false">66adf20af452caf50fb1fe1f</guid>
                
                    <category>
                        <![CDATA[ Chat ]]>
                    </category>
                
                    <category>
                        <![CDATA[ discord ]]>
                    </category>
                
                    <category>
                        <![CDATA[ messaging ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kolade Chris ]]>
                </dc:creator>
                <pubDate>Thu, 02 Dec 2021 17:10:47 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/12/Discord.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Discord is an instant messaging app that lets you communicate through voice, video, and texts. It is available in a web-based form, a desktop app, and a mobile app.</p>
<p>But sometimes, when you're trying to establish a voice call connection, you'll get an error that says “RTC Connecting Discord”. This message will keep showing without any meaningful progress.</p>
<p>So what does this error mean?</p>
<p>Discord uses the Real-time Chat protocol (RTC) to run concurrent communication. So if you are experiencing the “RTC Connecting Discord” problem, it is a network issue.</p>
<p>In this article, I will show you 5 changes you can make to your network configurations to fix the RTC Connecting Discord issue. 3 of the fixes involve your computer network settings, while the remaining 2 happen right in your Discord app. </p>
<h2 id="heading-how-to-fix-rtc-connecting-discord-by-updating-your-network-driver">How to Fix RTC Connecting Discord by Updating your Network Driver</h2>
<p>If your device relies on an outdated network adapter driver for internet connections, it could have a negative effect on your internet experience – and could cause this issue as well. </p>
<p>So, updating your network driver can fix the issue.</p>
<p><strong>The steps below take you through how you can update your network adapter driver.</strong></p>
<p><strong>Step 1</strong>: Click on Start (Windows logo) and search for "device manager". Hit <code>ENTER</code> to open the first search result – which is always Device Manager. You can click on the "Device Manager" search result, too.
<img src="https://www.freecodecamp.org/news/content/images/2021/12/ss-1.jpg" alt="ss-1" width="600" height="400" loading="lazy"></p>
<p><strong>Step 2</strong>: Expand "Network Adapters."</p>
<p><strong>Step 3</strong>: Look for the adapter in use, right-click on it and select "update driver".
<img src="https://www.freecodecamp.org/news/content/images/2021/12/ss-2.jpg" alt="ss-2" width="600" height="400" loading="lazy"></p>
<p><strong>Step 4</strong>: Select "Search automatically for drivers".
<img src="https://www.freecodecamp.org/news/content/images/2021/12/ss-3.jpg" alt="ss-3" width="600" height="400" loading="lazy"></p>
<p>Windows will now search the internet for an updated driver and install it for you.</p>
<h2 id="heading-how-to-fix-rtc-connecting-discord-by-changing-your-domain-name-server">How to Fix RTC Connecting Discord by Changing your Domain Name Server</h2>
<p>A domain name server (DNS) is assigned to you by your ISP (Internet Service Provider). Domain name servers make it possible to reach websites by typing addresses (URLs) to the browser instead of some unreadable numbers.</p>
<p>Changing this DNS to a widely used DNS like that of Google or Cloudflare can help you fix the RTC Connecting Discord issue.</p>
<p><strong>To change your DNS to Google’s, follow the steps below.</strong></p>
<p><strong>Step 1:</strong> Right-click on Start and choose “Run” to open the Run dialogue.
<img src="https://www.freecodecamp.org/news/content/images/2021/12/ss-4.jpg" alt="ss-4" width="600" height="400" loading="lazy"></p>
<p><strong>Step 2</strong>: Type in <code>“Control ncpa.cpl”</code> (without quotes) and hit <code>ENTER</code>. This will open up your network connection devices.
<img src="https://www.freecodecamp.org/news/content/images/2021/12/ss-5-2.png" alt="ss-5-2" width="600" height="400" loading="lazy"></p>
<p><strong>Step 3</strong>: Right-click on your current network and select “Properties”.
<img src="https://www.freecodecamp.org/news/content/images/2021/12/ss-6-1.jpg" alt="ss-6-1" width="600" height="400" loading="lazy"></p>
<p><strong>Step 4</strong>: Look for Internet Protocol Version 4 (TCP/IPv4) and double-click it.
<img src="https://www.freecodecamp.org/news/content/images/2021/12/ss-7.jpg" alt="ss-7" width="600" height="400" loading="lazy"></p>
<p><strong>Step 5</strong>: Click on the “Use the following DNS server address” radio button and type in the following values:</p>
<ul>
<li>8.8.8.8 for Preferred DNS Server</li>
<li>8.8.4.4 for Alternate DNS Server</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/ss-8.jpg" alt="ss-8" width="600" height="400" loading="lazy"></p>
<p><strong>Step 6</strong>: Click Ok.</p>
<p>Complete the setup with the next fix.</p>
<h2 id="heading-how-to-fix-rtc-connecting-discord-by-clearing-your-computer-network-cache-in-the-command-line">How to Fix RTC Connecting Discord by Clearing your Computer Network Cache in the Command Line</h2>
<p>If you’re using the web-based Discord, this fix can work for you.</p>
<p>You can clear your network cache on your browser, but a more effective way to do it is to clear it right on your Windows 10 computer in the command line.</p>
<p>The steps below show you how to do it.</p>
<p><strong>Step 1</strong>: Hit the <code>WIN</code> (Windows logo) key on your keyboard and search for "cmd". </p>
<p>You have to use the Command Prompt as an administrator, so you should select "Run as Administrator" on the right instead of just hitting <code>ENTER</code> to open it.</p>
<p><strong>Step 2</strong>: Enter and execute the following commands one after the other:</p>
<ul>
<li><code>ipconfig /release</code></li>
<li><code>ipconfig /flushdns</code></li>
<li><code>ipconfig /renew</code></li>
</ul>
<p><strong>Step 3</strong>: Restart your computer.
<img src="https://www.freecodecamp.org/news/content/images/2021/12/ss-9.png" alt="ss-9" width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/ss-10.png" alt="ss-10" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-fix-rtc-connecting-discord-by-disabling-qos">How to Fix RTC Connecting Discord by Disabling QoS</h2>
<p>Discord’s QoS (Quality of Service) communicates to your router that the units of data being transmitted are of high priority. This could make your router misbehave, and cause the RTC Connecting Discord issue. </p>
<p>So, disabling the QoS might fix it for you in case you have it enabled.</p>
<p><strong>Follow the steps below to disable QoS on Discord</strong>.</p>
<p><strong>Step 1</strong>: Launch Discord, then click on Settings on the bottom left corner. 
<img src="https://www.freecodecamp.org/news/content/images/2021/12/ss-11.jpg" alt="ss-11" width="600" height="400" loading="lazy"></p>
<p><strong>Step 2</strong>: Select Voice and Video on the left panel.
<img src="https://www.freecodecamp.org/news/content/images/2021/12/ss-12.jpg" alt="ss-12" width="600" height="400" loading="lazy"></p>
<p><strong>Step 3</strong>: Scroll down to the QoS section and disable it.
<img src="https://www.freecodecamp.org/news/content/images/2021/12/ss-13.jpg" alt="ss-13" width="600" height="400" loading="lazy"></p>
<p><strong>Step 4</strong>: Restart the Discord app.</p>
<h2 id="heading-how-to-fix-rtc-connecting-discord-by-changing-the-audio-subsystem-in-discord">How to Fix RTC Connecting Discord by Changing the Audio Subsystem in Discord</h2>
<p>In Discord, the Legacy audio subsystem has always been suggested as the best because it is the highest quality compared to the Standard and Experimental audio subsystems.</p>
<p>Changing your Audio subsystem to Legacy can make you establish quality audio – which can end up fixing the RTC Connecting Discord issue.</p>
<p><strong>These steps take you through how to change your Audio subsystem to Legacy</strong>.</p>
<p><strong>Step 1</strong>: Open Discord and click on Settings on the bottom left corner.<br><img src="https://www.freecodecamp.org/news/content/images/2021/12/ss-11.jpg" alt="ss-11" width="600" height="400" loading="lazy"></p>
<p><strong>Step 2</strong>: Select Voice and Video.
<img src="https://www.freecodecamp.org/news/content/images/2021/12/ss-12.jpg" alt="ss-12" width="600" height="400" loading="lazy"></p>
<p><strong>Step 3</strong>: Scroll down to the Audio Subsystem dropdown and select “Legacy”.
<img src="https://www.freecodecamp.org/news/content/images/2021/12/ss-14.jpg" alt="ss-14" width="600" height="400" loading="lazy"></p>
<p><strong>Step 4</strong>: Restart Discord. </p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>This article showed you how you can fix the RTC Connecting Discord problem you might experience when you are trying to use Discord's audio call feature.</p>
<p>Apart from the solutions explained in this article, you can try other minor fixes such as: </p>
<ul>
<li>Restarting your devices – computer and router</li>
<li>Double-checking internet connection</li>
<li>Using a VPN</li>
</ul>
<p>Thanks a lot for reading this article. If you find it helpful, share it with your friends and loved ones.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Chrome Extension Tutorial: How to Pass Messages from a Page's Context ]]>
                </title>
                <description>
                    <![CDATA[ By Tarique Ejaz In the world of web development, Chrome extensions are a pretty handy set of tools to have around.  Whether you use them to add headers to simple requests or to scrape important data from the DOM, extensions help provide extra functio... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/chrome-extension-message-passing-essentials/</link>
                <guid isPermaLink="false">66d4614a246e57ac83a2c7cf</guid>
                
                    <category>
                        <![CDATA[ Google Chrome ]]>
                    </category>
                
                    <category>
                        <![CDATA[ chrome extension ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ messaging ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 24 Feb 2021 02:14:59 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/02/DDF5E684-AEF5-45E6-9421-E5D4360E9A85-1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Tarique Ejaz</p>
<p>In the world of web development, Chrome extensions are a pretty handy set of tools to have around. </p>
<p>Whether you use them to add headers to simple requests or to scrape important data from the DOM, extensions help provide extra functionality that makes life easier.</p>
<p>I started playing around with developing a Chrome extension for a use-case I had in mind at work. It was then that I stumbled upon the way we pass around certain data from a web page to an extension. And the lack of a simplified guide made me write this article. </p>
<p>We do have the <a target="_blank" href="https://developer.chrome.com/docs/extensions/reference/">Chrome API documentation</a>, and it is indeed very thorough. But I consider myself to be more of a visual learner, and being able to visualize how we pass messages between the extension scripts helped simplify the overall development.</p>
<blockquote>
<p><strong>Note:</strong> This article makes use of Manifest V2 instead of V3. The major difference between the two is the usage of service workers in V3 instead of background pages and related actions. </p>
</blockquote>
<h2 id="heading-message-passing-interaction-between-scripts">Message Passing: Interaction Between Scripts</h2>
<p>An extension, as the name suggests, is like a layer on top of the existing webpage you're trying to access. The browser acts as the container.</p>
<p>It mainly comprises the following scripts:</p>
<ul>
<li><strong>Popup Script</strong> - Local JavaScript file for the extension DOM</li>
<li><strong>Background Script</strong> - Provides persistence and handles background events</li>
<li><strong>Content Script</strong> - Scripts that run in isolation in the context of the web page</li>
<li><strong>Injected Script</strong> - Scripts that are programmatically injected into the web page </li>
</ul>
<p>Normally, if you have to merely deal with the DOM content, then the way the extension is developed is relatively straightforward. </p>
<p>The raw HTML is already available to the content script and all you need to do is pass it to the popup script. </p>
<p>However, if you need to access the page's variables and functions, the process gets a little tricky.</p>
<p>The variables and functions available in the page context, say in the <code>window</code> object, are not accessible to the content scripts since they tend to run in a special JavaScript environment. They have access to only the DOM of the page but not the variables and functions. </p>
<p>To access a page's variables and functions, we inject scripts by appending them to the DOM. This makes the browser assume that it is run in the context of the web page. This in turn provides the injected script access to the local variables and functions.</p>
<p>Since Chrome extensions are event-driven because of their architecture, once the injected scripts have access to the page's variables and functions, they can pass it to the content script. </p>
<p>The content script then passes the these objects to the background page. </p>
<p>And finally, the popup script is able to call onto the background page using the Extension API and pass it to the Extension DOM. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/flowchart.png" alt="Image" width="600" height="400" loading="lazy">
<em>Message Passing Overview</em></p>
<p>Now, we will build a simple Performance Watcher extension that reads the performance data from the global window object of a page and maps the essential metrics for the user to see. Let's get into the code then.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/extn.PNG" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-enough-talk-show-me-the-code">Enough Talk, Show Me The Code</h2>
<p>You can find the complete code repository for the project <a target="_blank" href="https://github.com/tejazz/article-snippets/tree/master/chrome-extn-message-passing">here</a>. Let's quickly run through the primary files and the important functionalities they offer.</p>
<h3 id="heading-the-manifest-file">The Manifest File</h3>
<p>Every Chrome Extension needs a <code>manifest</code> file. It is basically a JSON-formatted file that provides a set of metadata so the browser can recognize the permissions that need to be granted and the likely operational reach of the extension. </p>
<p>Here is the manifest used for our application.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/manifest.png" alt="Image" width="600" height="400" loading="lazy">
<em>manifest.json: metadata for your extension</em></p>
<p>Some of the important properties we need to focus on are the following:</p>
<ul>
<li><code>background</code> - Takes an array of scripts that would be run in the background page. </li>
<li><code>content-scripts</code> - Includes an array of content scripts we wish to run as part of the web page's context. </li>
<li><code>web_accessible_resources</code> - An array of packaged resources expected to be used in a web page's context. For example, an image we intend to embed in a page or a custom script we want to inject.</li>
<li><code>permissions</code> - Allows your extension to gain access to certain Chrome APIs like <a target="_blank" href="https://developer.chrome.com/docs/extensions/reference/tabs/#type-Tab">tabs</a> in this case. </li>
</ul>
<h3 id="heading-the-content-script">The Content Script</h3>
<p>Content Scripts have easy access to the DOM of the web page. We make use of the content script to append our custom script – <code>inject-script.js</code> – into the DOM.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/content-inject.png" alt="Image" width="600" height="400" loading="lazy">
<em>content-script.js: inject custom script into the DOM</em></p>
<p>The content script also simultaneously continues to listen for any message being sent upstream from the custom script. </p>
<p>As soon as we get a message from the injected script, we run a quick check on the data received and verify whether our extension is installed. Once done, we simply use Chrome's <a target="_blank" href="https://developer.chrome.com/docs/extensions/reference/runtime/">Runtime API</a> to send the data received forward to the background page. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/content-send.png" alt="Image" width="600" height="400" loading="lazy">
<em>content-script.js: send the required data to the background page</em></p>
<h3 id="heading-the-injected-script">The Injected Script</h3>
<p>The custom script can access global variables and functions like the <code>window</code> object. We map only the properties we require. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/inject-action.png" alt="Image" width="600" height="400" loading="lazy">
<em>inject-script.js: procure required object from the page's JS context</em></p>
<p>The message from the custom script is communicated safely to the content script using the <code>[window.postMessage](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage)</code> function. In this case, a <code>setInterval</code> function is used to dynamically update the properties we are observing.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/inject-send.png" alt="Image" width="600" height="400" loading="lazy">
<em>inject-script.js: send the gathered data to the content-script</em></p>
<h3 id="heading-the-background-script">The Background Script</h3>
<p>The background script listens for any message transmitted by the content script using the Runtime API. The <code>window</code> object of the background page is then updated with the <code>tab.id</code> acting as the identifier. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/background.png" alt="Image" width="600" height="400" loading="lazy">
<em>background.js: listen for incoming message from the content-script</em></p>
<h3 id="heading-the-popup-script">The Popup Script</h3>
<p>The popup script is where we finally read the data we had procured from our custom script. It is also the place where we code any necessary JavaScript operations.</p>
<p>The background page is retrieved using the <code>getBackgroundPage</code> method of the Extension API. The active tab's id is queried using the <code>tabs.query</code> method of the Tabs API in order to correctly extract the relevant data.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/popup.png" alt="Image" width="600" height="400" loading="lazy">
<em>popup.js: reading the global object stored in the background page context</em></p>
<p>In this way, we are able to finally receive and map the data we need – <code>performance</code> in our case – efficiently in our extension.</p>
<p>The UI styling and other cosmetic code are available in the repository, for further reference.</p>
<h2 id="heading-final-thoughts">Final Thoughts</h2>
<p>Message passing is an essential concept when it comes to developing a Chrome extension. This is just one of the multiple ways in which you can communicate between scripts. </p>
<p>I spent a few hours in order to figure out how it would work for my use case. Hopefully, this simple walkthrough and the visual representation saves you some time. </p>
<p>I would suggest playing around with the code for a bit. If you have any questions, feel free to reach out to me on <code>[LinkedIn](https://www.linkedin.com/in/tarique-ejaz/)</code>.</p>
<p>In the meantime, keep coding.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Add Push Notifications to a Flutter App using Firebase Cloud Messaging ]]>
                </title>
                <description>
                    <![CDATA[ By Krissanawat Flutter has quickly become one the most popular frameworks for cross-platform mobile application development. It helps developers build native UIs with support for different device sizes, pixel densities, and orientations creating a be... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-add-push-notifications-to-flutter-app/</link>
                <guid isPermaLink="false">66d46021ffe6b1f641b5fa2a</guid>
                
                    <category>
                        <![CDATA[ Firebase ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Flutter ]]>
                    </category>
                
                    <category>
                        <![CDATA[ messaging ]]>
                    </category>
                
                    <category>
                        <![CDATA[ push notification ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 09 Dec 2020 19:57:23 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5fd0362ce6787e098393c56a.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Krissanawat</p>
<p>Flutter has quickly become one the most popular frameworks for cross-platform mobile application development. It helps developers build native UIs with support for different device sizes, pixel densities, and orientations creating a beautiful pixel-perfect UI/UX. </p>
<p>In this tutorial, we are going to learn how to add push notifications to a Flutter app using Firebase Cloud Messaging. This tutorial will only deal with configuration for the <strong>Android platform</strong>.</p>
<h3 id="heading-first-what-are-push-notifications">First, what are push notifications?</h3>
<p>Push Notifications are a sort of pop-up messaging medium that alerts app users to what's going on in the app. They are also an important way to amplify user engagement in your app. </p>
<p>For example, say a user forgets about the app once they have installed it. Then you can use push notifications as a mechanism to regain and retain their interest. Push notifications also help drive traffic to your app. </p>
<p>Firebase Cloud Messaging is a service offered by Firebase which lets you send these notifications to your users. You can set up various configurations to send different notifications to different audiences based on time and routine. </p>
<p>Because of all these benefits, we are going to use it to send notifications to our Flutter app.</p>
<h2 id="heading-step-1-create-a-flutter-project">Step 1: Create a Flutter Project</h2>
<p>First, we are going to create a flutter project. For that, we must have the Flutter SDK installed in our system. You can find simple steps for flutter installation in the official <a target="_blank" href="https://flutter.dev/docs/get-started/install">documentation</a>. </p>
<p>After you've successfully installed Flutter, you can simply run the following command in your desired directory to set up a complete Flutter project:</p>
<pre><code class="lang-jsx">flutter create pushNotification
</code></pre>
<p>After you've set up the project, navigate inside the project directory. Execute the following command in the terminal to run the project in either an available emulator or an actual device:</p>
<pre><code class="lang-bash">flutter run
</code></pre>
<p>After a successful build, you will get the following result in the emulator screen:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-69.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-step-2-integrate-firebase-configuration-with-flutter">Step 2: Integrate Firebase Configuration with Flutter</h2>
<p>In this step, we are going to integrate Firebase services with our Flutter project. But first, we need to create a Firebase project. The setup guidelines are also provided in the official <a target="_blank" href="https://firebase.google.com/docs/flutter/setup?platform=android">firebase documentation</a> for Flutter.</p>
<p>To create a Firebase project, we need to log in to <a target="_blank" href="https://firebase.google.com/">Firebase</a> and navigate to the console. There we can simply click on 'Add a project' to get our project started.</p>
<p>Then a window will appear asking to input the project's name. Here, I've kept the project name as <code>FlutterPushNotification</code> as shown in the screenshot below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-70.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>We can continue to the next step when the project has been created. After the project has been set up, we will get a project console as shown in the screenshot below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-71.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Here, we are going to set up Firebase for the Android platform. So we need to click on the Android icon displayed in the above screenshot. This will lead us to the interface to register Firebase with our Flutter app project.</p>
<h2 id="heading-step-3-register-firebase-to-your-android-app">Step 3: Register Firebase to Your Android App</h2>
<p>As the registration process is platform-specific, we are going to register our app for the Android platform. After clicking on the Android icon, we will be directed to an interface asking for the <strong>Android package name</strong>. </p>
<p>In order to add the package name of our Flutter project, we need to locate it first. The package name will be available in the <strong>./android/app/build.gradle</strong> file of your Flutter project. You will see something like this:</p>
<pre><code class="lang-jsx">com.example.pushNotification
</code></pre>
<p>We just need to copy it and paste it to the Android package name input field as shown in the screenshot below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-72.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>After that, we can simply click on the 'Register app' button. This will lead us to the interface where we can get the <strong>google-services.json</strong> file which will link our Flutter app to Firebase Google services. </p>
<p>We need to download the file and move it to the <strong>./android/app</strong> directory of our Flutter project. The instructions are also shown in the screenshot below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-73.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-step-4-add-firebase-configurations-to-native-files-in-your-flutter-project">Step 4: Add Firebase Configurations to Native Files in your Flutter Project</h2>
<p>Now in order to enable Firebase services in our Android app, we need to add the <a target="_blank" href="https://developers.google.com/android/guides/google-services-plugin">google-services plugin</a> to our Gradle files.</p>
<p>First in our <strong>root-level (project-level)</strong> Gradle file (<strong>android/build.gradle</strong>), we need to add rules to include the Google Services Gradle plugin. We need to check if the following configurations are available or not:</p>
<pre><code class="lang-jsx">buildscript {
  repositories {
    <span class="hljs-comment">// Check that you have the following line (if not, add it):</span>
    google()  <span class="hljs-comment">// Google's Maven repository</span>
  }
  dependencies {
    ...
    <span class="hljs-comment">// Add this line</span>
    classpath <span class="hljs-string">'com.google.gms:google-services:4.3.4'</span>
  }
}

allprojects {
  ...
  repositories {
    <span class="hljs-comment">// Check that you have the following line (if not, add it):</span>
    google()  <span class="hljs-comment">// Google's Maven repository</span>
    ...
  }
}
</code></pre>
<p>If not, we need to add the configurations as shown in the code snippet above.</p>
<p>Now in our module (app-level) Gradle file (<strong>android/app/build.gradle</strong>), we need to apply the <strong>Google Services Gradle</strong> plugin. </p>
<p>For that, we need to add the piece of code highlighted in the following code snippet to the <strong>./android/app/build.gradle</strong> file of our project:</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// Add the following line:</span>
**apply plugin: <span class="hljs-string">'com.google.gms.google-services'</span>**  <span class="hljs-comment">// Google Services plugin</span>

android {
  <span class="hljs-comment">// ...</span>
}
</code></pre>
<p>Now, we need to run the following command so that some automatic configurations can be made:</p>
<pre><code class="lang-jsx">flutter packages get
</code></pre>
<p>With that we have successfully integrated Firebase configurations with our Flutter project.</p>
<h2 id="heading-step-5-integrate-firebase-messaging-with-flutter">Step 5: Integrate Firebase Messaging with Flutter</h2>
<p>First, we need to add the firebase-messaging dependency to the <strong>./android/app/build.gardle</strong> file. In the file, we need to add the following dependencies:</p>
<pre><code class="lang-dart">dependencies {
    implementation <span class="hljs-string">"org.jetbrains.kotlin:kotlin-stdlib-jdk7:<span class="hljs-subst">$kotlin_version</span>"</span>
    implementation <span class="hljs-string">'com.google.firebase:firebase-messaging:20.1.0'</span>
}
</code></pre>
<p>Next, we need to add an <code>action</code> and a <code>category</code> as an <code>intent-filter</code> within the <code>activity</code> tag in the <strong>./android/app/src/main/AndroidManifest.xm</strong>l file:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">intent-filter</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">action</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"FLUTTER_NOTIFICATION_CLICK"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">category</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"android.intent.category.DEFAULT"</span> /&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">intent-filter</span>&gt;</span>
</code></pre>
<p>Now, we need to create a Java file called <strong>Application.java</strong> in the path <strong>/android/app/src/main/java/</strong>.</p>
<p>Then, we need to add the code from the following code snippet inside it:</p>
<pre><code class="lang-java"><span class="hljs-keyword">package</span> io.flutter.plugins.pushNotification;

<span class="hljs-keyword">import</span> io.flutter.app.FlutterApplication;
<span class="hljs-keyword">import</span> io.flutter.plugin.common.PluginRegistry;
<span class="hljs-keyword">import</span> io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback;
<span class="hljs-keyword">import</span> io.flutter.plugins.GeneratedPluginRegistrant;
<span class="hljs-keyword">import</span> io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin;
<span class="hljs-keyword">import</span> io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService;

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Application</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">FlutterApplication</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">PluginRegistrantCallback</span> </span>{
    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onCreate</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">super</span>.onCreate();
        FlutterFirebaseMessagingService.setPluginRegistrant(<span class="hljs-keyword">this</span>);
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">registerWith</span><span class="hljs-params">(PluginRegistry registry)</span> </span>{
        FirebaseMessagingPlugin.registerWith(registry.registrarFor(<span class="hljs-string">"io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"</span>));
    }
}
</code></pre>
<p>Now, we need to assign this <code>Application</code> activity to the <code>application</code> tag of the <strong>AndroidManifest.xml</strong> file as shown in the code snippet below:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">application</span>
        <span class="hljs-attr">android:name</span>=<span class="hljs-string">".Application"</span></span>
</code></pre>
<p>This completes our setup of the Firebase messaging plugin in the native Android code. Now, we'll move on to the Flutter project.</p>
<h2 id="heading-step-6-install-the-firebase-messaging-package">Step 6: Install the Firebase Messaging Package</h2>
<p>Here, we are going to use the <code>[firebase_messaging</code>] package, which <a target="_blank" href="https://pub.dev/packages/firebase_messaging/">you can find here</a>. For that, we need to add the plugin to the dependency option of the pubspec.yaml file. </p>
<p>We need to add the following line of code to the dependencies option:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">firebase_messaging:</span> <span class="hljs-string">^7.0.3</span>
</code></pre>
<h2 id="heading-step-7-implement-a-simple-ui-screen">Step 7: Implement a Simple UI Screen</h2>
<p>Now, inside the <code>MyHomePage</code> stateful widget class of the <strong>main.dart</strong> file, we need to initialize the <code>FirebaseMessaging</code> instance and some constants as shown in the code snippet below:</p>
<pre><code class="lang-dart"><span class="hljs-built_in">String</span> messageTitle = <span class="hljs-string">"Empty"</span>;
<span class="hljs-built_in">String</span> notificationAlert = <span class="hljs-string">"alert"</span>;

FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
</code></pre>
<p>The <code>messageTitle</code> variable will receive the notification message title and <code>notificationAlert</code> will be assigned the action that's been completed once the notification comes up.</p>
<p>Now, we need to apply these variables to the build function inside the <code>Scaffold</code> widget body as shown in the code snippet below:</p>
<pre><code class="lang-dart">Widget build(BuildContext context) {
    <span class="hljs-keyword">return</span> Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: &lt;Widget&gt;[
            Text(
              notificationAlert,
            ),
            Text(
              messageTitle,
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
    );
  }
</code></pre>
<p>Next, we need to run the Flutter application by executing the following command in the project terminal:</p>
<pre><code class="lang-bash">flutter run
</code></pre>
<p>We will get the result you see in the image below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-74.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>For now, the notification title is empty, and the alert is also as defined. We need to assign a proper value to them once we receive the notification message.</p>
<p>So we need to configure the code to receive the notification and use the notification message to display it on the screen.</p>
<p>For that, we need to add the code from the following code snippet in the <code>initiState</code> function:</p>
<pre><code class="lang-dart"><span class="hljs-meta">@override</span>
  <span class="hljs-keyword">void</span> initState() {
    <span class="hljs-comment">// <span class="hljs-doctag">TODO:</span> implement initState</span>
    <span class="hljs-keyword">super</span>.initState();

    _firebaseMessaging.configure(
      onMessage: (message) <span class="hljs-keyword">async</span>{
        setState(() {
          messageTitle = message[<span class="hljs-string">"notification"</span>][<span class="hljs-string">"title"</span>];
          notificationAlert = <span class="hljs-string">"New Notification Alert"</span>;
        });

      },
      onResume: (message) <span class="hljs-keyword">async</span>{
        setState(() {
          messageTitle = message[<span class="hljs-string">"data"</span>][<span class="hljs-string">"title"</span>];
          notificationAlert = <span class="hljs-string">"Application opened from Notification"</span>;
        });

      },
    );
  }
</code></pre>
<p>Here, we have used the <code>configure</code> method provided by <code>_firebaseMessaging</code> instance which in turn provides the <code>onMessage</code> and <code>onResume</code> callbacks. These callbacks provide the notification <code>message</code> as a parameter. The <code>message</code> response will hold the notification object as a map object.</p>
<p>The <code>onMessage</code> function triggers when the notification is received while we are running the app. The <code>onResume</code> function triggers when we receive the notification alert in the device notification bar and opens the app through the push notification itself. In this case, the app can be running in the background or not running at all.</p>
<p>Now we are all equipped with the Flutter app. We just need to configure a message in Firebase Cloud Messaging and send it to the device.</p>
<h2 id="heading-step-8-create-a-message-from-the-firebase-cloud-messaging-console">Step 8: Create a Message from the Firebase Cloud Messaging Console</h2>
<p>First, we need to go back to the Cloud Messaging console in the Firebase site as shown in the image below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-75.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Here, we can see the 'Send your first message' option in the window, as we have not configured any messages before. We need to click on it which will lead us to the following window:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-76.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Here, we can enter the title, text, image, and name of the notification. The title we set here will be provided as the title in the <code>message</code> object on the callbacks we set before in the Flutter project.</p>
<p>After setting the required fields, we can click on 'Next' which will lead us to the following window:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-77.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Here, we need to provide our target app and click on 'Next'.</p>
<p>For Scheduling we can keep the default option:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-78.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Next, the Conversion window will appear which we can keep as default as well, and then click on the 'Next' button.</p>
<p>Lastly, a window where we need to enter the custom data will appear in which we can set the <code>title</code> and <code>click_action</code>. This click action event is triggered whenever we click on the notification that appears in the notification bar of the device. </p>
<p>After clicking on the notification message from the notification bar, the app will open and the <code>onResume</code> callback will trigger, setting <code>title</code> as assigned in the custom data in the screenshot below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/12/image-79.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Now, we are ready to send the first notification message to the device. First, let's try it with the device running in the emulator.</p>
<p>As we click on the 'Review' button and send the message, we will get the following result in the Cloud Messaging console as well as the emulator:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/12/pushGIF1.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Here, we can see that the title and the notification alert on the emulator screen are updated as soon as we send a message from the console. We can be sure that the <code>onMessage</code> callback was triggered in the app after receiving the notification message.</p>
<p>Now let's try with the app running in the background. As we send the message from the console, we will get the result as shown in the demo below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/12/pushGIF2.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Here, as soon as we send the message, we receive a push notification in the notification bar of the device. Then, as we drag down the notification bar, we can see the notification message title and text. And, by clicking on the notification message, we can launch the application and display the custom data on the screen. This ensures that our <code>onResume</code> callback was triggered.</p>
<p>And we're done! We have successfully added a push notification feature in our Flutter application using Firebase Cloud Messaging.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Push notifications are essential in any app. They can be used to alert users to what's going on in the app, and can help drive users' interest back to the app. </p>
<p>Additionally, Firebase Cloud Messaging makes sending notification alerts much simpler and easier. </p>
<p>In this tutorial, we started by configuring the Firebase app and then moved on to the setup and implementation of the Firebase messaging configuration in the Flutter app. Lastly, we were able to send notification alerts to the app using Firebase Cloud Messaging. </p>
<p>The tutorial was meant to be simple and easy to understand. Hope that it helps you add push notification to your Flutter apps. Want to see some examples of how you can implement all this? Check out these powerful <a target="_blank" href="http://instaflutter.com">Flutter templates</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Async Messaging with RabbitMQ and Tortoise in Node.js ]]>
                </title>
                <description>
                    <![CDATA[ RabbitMQ happens to be the easiest and most performant message broker platform using the AMQ protocol out there today. Using it in a microservice architecture translates into massive performance gains, as well as the promise of reliability.  In this ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/async-messaging-with-rabbitmq-tortoise/</link>
                <guid isPermaLink="false">66c34505f9d371e3aae26833</guid>
                
                    <category>
                        <![CDATA[ messaging ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ toothbrush ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 03 Feb 2020 01:04:00 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c9cd7740569d1a4ca3478.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>RabbitMQ happens to be the easiest and most performant message broker platform using the AMQ protocol out there today. Using it in a microservice architecture translates into massive performance gains, as well as the promise of reliability. </p>
<p>In this guide, we’re going to explore the basics of using RabbitMQ with Node.js.</p>
<h2 id="heading-theory"><strong>Theory</strong></h2>
<p>At its most basic level, you’d ideally have two different services interacting with one another through Rabbit - a <em>publisher</em> and a <em>subscriber</em>. </p>
<p>A publisher typically pushes messages to Rabbit, and a subscriber listens to these messages, and executes code on the basis of those messages. </p>
<p>Note that they can be both at the same time - a service can publish messages to Rabbit and consume messages at the same time, which allows really powerful systems to be designed.</p>
<p>Now a publisher typically publishes messages with a <em>routing key</em> to something called an <em>exchange</em>. A consumer listens to a <em>queue</em> on the same exchange, bound to the routing key. </p>
<p>In architectural terms, your platform would use one Rabbit exchange, and different kinds of jobs/services would have their own routing keys and queues, in order for pub-sub to work effectively. </p>
<p>Messages can be strings; they can also be native objects - AMQP client libraries do the heavy lifting of converting objects from one language to another. And yes, that does mean services can be written in different languages, so long as they’re able to understand AMQP.</p>
<h2 id="heading-getting-started"><strong>Getting started</strong></h2>
<p>We’re going to cook up a very simple example where a publisher script publishes a message to Rabbit, containing a URL, and a consumer script listens to Rabbit, takes the published URL, calls it and displays the results. You can find the finished sample up on <a target="_blank" href="https://github.com/rudimk/freecodecamp-guides-rabbitmq-tortoise">Github</a>.</p>
<p>First, let’s initialize a npm project:</p>
<p><code>$ npm init</code></p>
<p>You can always just hit <code>Enter</code> all the way and use the default options - or you can fill them up. </p>
<p>Now, let’s install the packages we need. We’re going to use <a target="_blank" href="https://www.npmjs.com/package/tortoise">Tortoise</a> to interact with RabbitMQ. We’re also going to use <a target="_blank" href="https://www.npmjs.com/package/node-cron">node-cron</a> to schedule the actual message publishing.</p>
<p><code>$ npm install --save tortoise node-cron</code></p>
<p>Now your <code>package.json</code> should look a lot like this:</p>
<pre><code class="lang-text">{
  "name": "freecodecamp-guides-rabbitmq-tortoise",
  "version": "1.0.0",
  "description": "Sample code to accompany the FreeCodeCamp guide on async messaging with RabbitMQ and Tortoise.",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" &amp;&amp; exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/rudimk/freecodecamp-guides-rabbitmq-tortoise.git"
  },
  "keywords": [
    "rabbitmq",
    "tortoise",
    "amqp"
  ],
  "author": "Rudraksh M.K.",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/rudimk/freecodecamp-guides-rabbitmq-tortoise/issues"
  },
  "homepage": "https://github.com/rudimk/freecodecamp-guides-rabbitmq-tortoise#readme",
  "dependencies": {
    "node-cron": "^1.2.1",
    "tortoise": "^1.0.1"
  }
}
</code></pre>
<p>Now we’re all set. Let’s create a publisher first.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> Tortoise = <span class="hljs-built_in">require</span>(<span class="hljs-string">'tortoise'</span>)
<span class="hljs-keyword">const</span> cron = <span class="hljs-built_in">require</span>(<span class="hljs-string">'node-cron'</span>)

<span class="hljs-keyword">const</span> tortoise = <span class="hljs-keyword">new</span> Tortoise(<span class="hljs-string">`amqp://rudimk:YouKnowWhat@$localhost:5672`</span>)
</code></pre>
<p>After importing <code>tortoise</code> and <code>node-cron</code>, we’ve gone ahead and initialized a connection to RabbitMQ. Next, let’s write a quick and dirty function that publishes a message to Rabbit:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">scheduleMessage</span>(<span class="hljs-params"></span>)</span>{
    <span class="hljs-keyword">let</span> payload = {<span class="hljs-attr">url</span>: <span class="hljs-string">'https://randomuser.me/api'</span>}
    tortoise
    .exchange(<span class="hljs-string">'random-user-exchange'</span>, <span class="hljs-string">'direct'</span>, { <span class="hljs-attr">durable</span>:<span class="hljs-literal">false</span> })
    .publish(<span class="hljs-string">'random-user-key'</span>, payload)
}
</code></pre>
<p>That’s simple enough. We’ve defined a dictionary containing a URL to the <a target="_blank" href="https://randomuser.me/">RandomUser.me</a> API, which is then published to the <code>random-user-exchange</code> exchange on RabbitMQ, with the <code>random-user-key</code> routing key. </p>
<p>As mentioned earlier, the routing key is what determines who gets to consume a message. Now, let’s write a scheduling rule, to publish this message every 60 seconds.</p>
<pre><code class="lang-javascript">cron.schedule(<span class="hljs-string">'60 * * * * *'</span>, scheduleMessage)
</code></pre>
<p>And our publisher’s ready! But it’s really no good without a consumer to actually consume these messages! But first, we do need a library that can call the URL in these messages. Personally, I use <code>superagent</code>: <code>npm install --save superagent</code>.</p>
<p>Now, in <code>consumer.js</code>:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> Tortoise = <span class="hljs-built_in">require</span>(<span class="hljs-string">'tortoise'</span>)
<span class="hljs-keyword">const</span> superagent = <span class="hljs-built_in">require</span>(<span class="hljs-string">'superagent'</span>)

<span class="hljs-keyword">const</span> tortoise = <span class="hljs-keyword">new</span> Tortoise(<span class="hljs-string">`amqp://rudimk:YouKnowWhat@$localhost:5672`</span>)
</code></pre>
<p>Next, let’s write an async function that calls a URL and displays the result:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getURL</span>(<span class="hljs-params">url</span>)</span>{
    <span class="hljs-keyword">let</span> response = <span class="hljs-keyword">await</span> superagent.get(url)
    <span class="hljs-keyword">return</span> response.body
}
</code></pre>
<p>Time to write code to actually consume messages:</p>
<pre><code class="lang-javascript">tortoise
.queue(<span class="hljs-string">'random-user-queue'</span>, { <span class="hljs-attr">durable</span>: <span class="hljs-literal">false</span> })
<span class="hljs-comment">// Add as many bindings as needed </span>
.exchange(<span class="hljs-string">'random-user-exchange'</span>, <span class="hljs-string">'direct'</span>, <span class="hljs-string">'random-user-key'</span>, { <span class="hljs-attr">durable</span>: <span class="hljs-literal">false</span> })
.prefetch(<span class="hljs-number">1</span>)
.subscribe(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">msg, ack, nack</span>) </span>{
  <span class="hljs-comment">// Handle </span>
  <span class="hljs-keyword">let</span> payload = <span class="hljs-built_in">JSON</span>.parse(msg)
  getURL(payload[<span class="hljs-string">'url'</span>]).then(<span class="hljs-function">(<span class="hljs-params">response</span>) =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Job result: '</span>, response)
  })
  ack() <span class="hljs-comment">// or nack()</span>
})
</code></pre>
<p>Here, we’ve told <code>tortoise</code> to listen to the <code>random-user-queue</code>, that’s bound to the <code>random-user-key</code> on the <code>random-user-exchange</code>. Once a message is received, the payload is retrieved from <code>msg</code>, and is passed along to the <code>getURL</code> function, which in turn returns a Promise with the desired JSON response from the RandomUser API.</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>The simplicity associated with using RabbitMQ for messaging is unparalleled, and it’s very easy to come up with really complex microservice patterns with just a few lines of code. </p>
<p>The best part is that the logic behind messaging doesn’t really change across languages - Crystal or Go or Python or Ruby work with Rabbit in pretty much the same way. This means you can have services written in different languages all communicating with each other effortlessly, enabling you to use the best language for the job.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to choose the best event source for pub/sub messaging with AWS Lambda ]]>
                </title>
                <description>
                    <![CDATA[ By Yan Cui AWS offers a wealth of options for imple­ment­ing mes­sag­ing pat­terns such as Publish/Subscribe (often short­ened to pub/sub) with AWS Lamb­da. In this article, we’ll com­pare and con­trast some of these options. The pub/sub pattern Pub/... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-choose-the-best-event-source-for-pub-sub-messaging-with-aws-lambda-31ca4db9be69/</link>
                <guid isPermaLink="false">66c3508a5ced6d98e4bd3340</guid>
                
                    <category>
                        <![CDATA[ AWS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ messaging ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Tutorial ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 02 Apr 2018 21:38:42 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/0*dEUcN2mmJXDmiwb8.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Yan Cui</p>
<p>AWS offers a wealth of options for imple­ment­ing mes­sag­ing pat­terns such as <code>Publish/Subscribe</code> (often short­ened to pub/sub) with AWS Lamb­da. In this article, we’ll com­pare and con­trast some of these options.</p>
<h3 id="heading-the-pubsub-pattern">The pub/sub pattern</h3>
<p>Pub/Sub is a mes­sag­ing pat­tern where pub­lish­ers and sub­scribers are decou­pled through an inter­me­di­ary message bro­ker (ZeroMQ, Rab­bit­MQ, SNS, and so on).</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/aMYeJtlvg8qD1aw7GWlpLcrptCADpvXiGRlt" alt="Image" width="800" height="101" loading="lazy">
_Source: [Publish Subscribe Pattern (Wikipedia)](https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern" rel="noopener" target="<em>blank" title=")</em></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/in-2N2y0wjCxQdEAMjGcplRv7yUWRfMvewOr" alt="Image" width="800" height="435" loading="lazy"></p>
<p>In the AWS ecosys­tem, the obvi­ous can­di­date for the bro­ker role is Simple Notification Service (SNS).</p>
<p>SNS will make three attempts for your Lambda func­tion to process a mes­sage before send­ing it to a Dead Let­ter Queue (DLQ) if a DLQ is spec­i­fied for the func­tion. How­ev­er, accord­ing to an <a target="_blank" href="https://engineering.opsgenie.com/aws-lambda-performance-series-part-2-an-analysis-on-async-lambda-fail-retry-behaviour-and-dead-b84620af406">analy­sis</a> by the folks at Ops­Ge­nie, the number of retries can be as many as six.</p>
<p>Anoth­er thing to con­sid­er is the degree of par­al­lelism this set­up offers. For each mes­sage, SNS will cre­ate a new invo­ca­tion of your func­tion. So if you pub­lish 100 mes­sages to SNS, then you can have 100 con­cur­rent exe­cu­tions of the sub­scribed Lamb­da func­tion.</p>
<p><strong>This is great if you’re opti­mis­ing for through­put</strong>.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/lKqW9l3keN4ybs4AHSxxJSu76E22YUADwgWE" alt="Image" width="800" height="402" loading="lazy"></p>
<p>How­ev­er, we’re often <strong>con­strained</strong> by the max through­put our down­stream depen­den­cies can han­dle — data­bas­es, S3, internal/external ser­vices, and so on.</p>
<p>If the burst in through­put is short, then there’s a good chance the retries would be suf­fi­cient (there’s a ran­domized, expo­nen­tial back off between retries too) and you won’t miss any mes­sages.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/aUrhbLV0y5hatCjtR-kpZuvzi6eQZBmM9Gtz" alt="Image" width="800" height="332" loading="lazy">
<em>Erred messages are retried 2 times with exponential back off. If the burst is short-lived then the retry is likely to succeed, resulting in no message loss.</em></p>
<p>If the burst in through­put is sus­tained over a long peri­od of time, then you can exhaust the max number of retries. At this point you’ll have to rely on the DLQ and pos­si­bly human inter­ven­tion in order to recov­er the mes­sages that couldn’t be processed the first time around.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/2uzNYBIHpLiAdHSsZBRl9aLIXXbKM5mQ5LBG" alt="Image" width="800" height="340" loading="lazy">
<em>Erred messages are retried 2 times with exponential back off. But the burst in message rate overlaps with the retries, further exacerbating the problem and eventually the max number of retries are exhausted and erred messages have to be delivered to the DLQ instead (if one is specified).</em></p>
<p>Sim­i­lar­ly, if the down­stream depen­den­cy expe­ri­ences an out­age, then all mes­sages received and retried dur­ing the out­age are bound to fail.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/PFbSpQtb0Nxx2RREF9VATvUBjJxR5lxu0WD5" alt="Image" width="800" height="336" loading="lazy">
<em>Any message received or retried during the downstream message will fail and be sent to the DLQ.</em></p>
<p>You can also run into the <a target="_blank" href="http://docs.aws.amazon.com/lambda/latest/dg/limits.html">Lamb­da lim­it</a> on the number of con­cur­rent exe­cu­tions in a region. Since this is an account-wide lim­it, it will also impact your oth­er sys­tems within the account that rely on AWS Lamb­da: APIs, event pro­cess­ing, cron jobs, and so on.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/MdSMzBdPAvsgSkw47bXD2Dj8qlB4K9y0v5fd" alt="Image" width="800" height="420" loading="lazy"></p>
<p>SNS is also prone to suf­fer from tem­po­ral issues, like bursts in traf­fic, down­stream out­age, and so on. Kine­sis, on the oth­er hand, deals with these issues much bet­ter as described below:</p>
<ul>
<li>The degree of par­al­lelism is con­strained by the number of shards, which can be used to amor­tize bursts in the mes­sage rate</li>
</ul>
<p><img src="https://cdn-media-1.freecodecamp.org/images/MvIaF-A3FjeFNn5GSzSRzJ3vD-fcdF5kZv9q" alt="Image" width="800" height="308" loading="lazy">
<em>Bursts in message rate is amortised, as the max throughput is determined by no. of shards <em> max batch size </em> 5 reads per second. Which gives you two levers to adjust the max throughput with.</em></p>
<ul>
<li>Records are retried until suc­cess is achieved, unless the out­age lasts longer than the reten­tion pol­i­cy you have on the stream (the default is 24 hours). You will even­tu­al­ly be able to process the records</li>
</ul>
<p><img src="https://cdn-media-1.freecodecamp.org/images/v8c03ATaEUayJurzgbxbPSWtqG-rebS7v40U" alt="Image" width="800" height="312" loading="lazy">
<em>The impact of a downstream outage is absorbed by the retry-until-success invocation policy.</em></p>
<p>But Kine­sis Streams is not with­out its own prob­lems. In fact, from my expe­ri­ence using Kine­sis Streams with Lamb­da, I have found a number of caveats that need­ to be under­stood in order to make effec­tive use of the service.</p>
<p>You can read about these caveats in another article I wrote <a target="_blank" href="https://read.acloud.guru/aws-lambda-3-pro-tips-for-working-with-kinesis-streams-8f6182a03113">here</a>.</p>
<p>Inter­est­ing­ly, Kine­sis Streams is not the only stream­ing option avail­able on AWS. There is also DynamoDB Streams.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/ZVV6125FoRnsc-WWr5xDeiQdYMgdJgbxZFbn" alt="Image" width="800" height="358" loading="lazy">
<em>DynamoDB Streams can be used as a like-for-like replacement for Kinesis Streams.</em></p>
<p>By and large, DynamoDB Streams + Lamb­da works the same way as Kine­sis Streams + Lamb­da. Oper­a­tional­ly, it does have some inter­est­ing twists:</p>
<ul>
<li>DynamoDB Streams auto scales the number of shards</li>
<li>If you’re pro­cess­ing DynamoDB Streams with AWS Lamb­da, then you don’t pay for the reads from DynamoDB Streams (but you still pay for the read and write capac­i­ty units for the DynamoDB table itself)</li>
</ul>
<p><img src="https://cdn-media-1.freecodecamp.org/images/elMIs2s1bvzsS3t1s6lck8kKjUQtoN16p2d6" alt="Image" width="800" height="382" loading="lazy">
_Source: [DynamoDB Pricing](https://aws.amazon.com/dynamodb/pricing/" rel="noopener" target="<em>blank" title=")</em></p>
<ul>
<li>Kine­sis Streams offers the option to extend data reten­tion to 7 days, but DynamoDB Streams doesn’t offer such an option</li>
</ul>
<p><img src="https://cdn-media-1.freecodecamp.org/images/ZfHR49h8Odv-6oORBUdbEoulWBpkeTobaFSV" alt="Image" width="800" height="241" loading="lazy">
_Source: [Working with DynamoDB Streams](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.html" rel="noopener" target="<em>blank" title=")</em></p>
<p>The fact that DynamoDB Streams auto scales the number of shards can be a dou­ble-edged sword. On one hand, it elim­i­nates the need for you to man­age and scale the stream (or come up with home-baked <a target="_blank" href="https://read.acloud.guru/auto-scaling-kinesis-streams-with-aws-lambda-299f9a0512da">auto scal­ing solu­tions</a>). But on the oth­er hand, it can also dimin­ish the abil­i­ty to amor­tize spikes in the load you pass on to down­stream sys­tems.</p>
<p>As far as I know, there is no way to lim­it the number of shards a DynamoDB stream can scale up to, which is some­thing you’d sure­ly con­sid­er when imple­ment­ing your own auto scal­ing solu­tion.</p>
<p>I think the most per­ti­nent ques­tion is, <code>“what is your source of truth?”</code></p>
<p>Does a row being writ­ten in DynamoDB make it canon to the state of your system? This is cer­tain­ly the case in most N-tier sys­tems that are built around a data­base, regard­less of whether it’s an RDBMS or NoSQL database.</p>
<p>In an event-sourced sys­tem where state is mod­eled as a sequence of events (as opposed to a snap­shot), the source of truth might well be the Kine­sis stream. For example, as soon as an event is writ­ten to the stream, it’s con­sid­ered canon to the state of the sys­tem.</p>
<p>Then, there’re oth­er con­sid­er­a­tions around cost, auto-scal­ing, and so on.</p>
<p>From a devel­op­ment point of view, DynamoDB streams also have some limitations and short­com­ings:</p>
<ul>
<li>Each stream is lim­it­ed to events from one table</li>
<li>The records describe DynamoDB events and not events from your domain, which I’ve always felt cre­ates a sense of dis­so­nance when work­ing with these events</li>
</ul>
<p>Exclud­ing the cost of Lamb­da invo­ca­tions for pro­cess­ing the mes­sages, here are some cost pro­jec­tions for using SNS vs Kine­sis Streams vs DynamoDB Streams as the bro­ker. I’m mak­ing the assump­tion that through­put is con­sis­tent, and that each mes­sage is 1KB in size.</p>
<p><strong>Month­ly cost at 1 msg/s</strong></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/yyuEQdQUtDXmaG-3FeSvBuM3Y1quo52SkIQY" alt="Image" width="800" height="313" loading="lazy"></p>
<p><strong>Month­ly cost at 1,000 msg/s</strong></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/11RcJ9KEIfnJbOCXvUz8g2J2AR6K5lKuGsNX" alt="Image" width="800" height="299" loading="lazy"></p>
<p><strong>These pro­jec­tions should not be tak­en at face val­ue.</strong> For starters, the assump­tion about a per­fect­ly con­sis­tent through­put and mes­sage size is unre­al­is­tic, and you’ll need some head­room with Kine­sis and DynamoDB streams even if you’re not hit­ting the throt­tling lim­its.</p>
<p>That said, what these pro­jec­tions do tell me is that:</p>
<ol>
<li>You get an awful lot with each shard in Kine­sis streams</li>
<li>While there’s a base­line cost for using Kine­sis streams, the cost goes down when usage scales up as com­pared to SNS and DynamoDB streams, thanks to the sig­nif­i­cant­ly low­er cost per mil­lion requests</li>
</ol>
<p>Whilst SNS, Kine­sis, and DynamoDB streams are your basic choic­es for the bro­ker, Lamb­da func­tions can also act as bro­kers in their own right and prop­a­gate events to oth­er ser­vices.</p>
<p>This is the approach used by the <a target="_blank" href="https://github.com/awslabs/aws-lambda-fanout">aws-lamb­da-fanout</a> project from awslabs. It allows you to prop­a­gate events from Kine­sis and DynamoDB streams to oth­er ser­vices that can­not direct­ly sub­scribe to the three basic choice of bro­kers (either because of account/region lim­i­ta­tions or that they’re just not sup­port­ed).</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/arPDE4lmFHJ-GPKb3u-366nUFaDeaZxiyZp8" alt="Image" width="661" height="430" loading="lazy">
<em>The aws-lambda-fanout project from awslabs propagates events from Kinesis and DynamoDB Streams to other services across multiple accounts and regions.</em></p>
<p>While it’s a nice idea and def­i­nite­ly meets some spe­cif­ic needs, it’s worth bear­ing in mind the extra com­plex­i­ties it intro­duces, such as han­dling par­tial fail­ures, deal­ing with down­stream out­ages, mis­con­fig­u­ra­tions, and so on.</p>
<h3 id="heading-conclusion">Conclusion</h3>
<p>So what is the best event source for doing pub-sub with AWS Lamb­da? Like most tech deci­sions, it depends on the <strong>prob­lem</strong> you’re try­ing to solve, and the <strong>con­straints</strong> you’re work­ing with.</p>
<p>In this post, we looked at SNS, Kine­sis Streams, and DynamoDB Streams as can­di­dates for the bro­ker role. We walked through a num­ber of sce­nar­ios to see how the choice of event source affects scal­a­bil­i­ty, par­al­lelism, and resilience against tem­po­ral issues and cost.</p>
<p>You should now have a much bet­ter under­stand­ing of the trade­offs between various event sources when work­ing with Lamb­da.</p>
<p>Until next time!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ HTTPS explained with carrier pigeons ]]>
                </title>
                <description>
                    <![CDATA[ By Andrea Zanin Korean translationPortuguese translationSpanish translationMongolian translationPersian translationVietnamese translation Cryptography can be a hard subject to understand. It’s full of mathematical proofs. But unless you are actually ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/https-explained-with-carrier-pigeons-7029d2193351/</link>
                <guid isPermaLink="false">66c356fd0cede4e9b1329c7c</guid>
                
                    <category>
                        <![CDATA[ Cryptography ]]>
                    </category>
                
                    <category>
                        <![CDATA[ humor ]]>
                    </category>
                
                    <category>
                        <![CDATA[ messaging ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Security ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 10 Jan 2018 22:07:10 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*vHF6NNdZX9ziiW_uRYzvAA.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Andrea Zanin</p>
<p><a target="_blank" href="https://www.vobour.com/%EB%B9%84%EB%91%98%EA%B8%B0%EB%A1%9C-%EC%84%A4%EB%AA%85%ED%95%98%EB%8A%94-https-https-explained-with-car">Korean translation</a><br><a target="_blank" href="https://medium.com/inpaas/explicando-https-com-pombos-correio-68270a5b0c28">Portuguese translation</a><br><a target="_blank" href="https://www.transparentcdn.com/https-explicado-palomas-mensajeras/">Spanish translation</a><br><a target="_blank" href="https://medium.com/unimediasolutions/https-ыг-шууданч-тагтаагаар-адилтган-тайлбарлах-нь-f094d38a7dc5">Mongolian translation</a><br><a target="_blank" href="https://virgool.io/@raminpay/https-explained-hkxu4qmijmfc">Persian translation</a><br><a target="_blank" href="https://blogchanhday.com/p/nhat-ky-anh-bo-cau-dua-thu-va-https/">Vietnamese translation</a></p>
<p>Cryptography can be a hard subject to understand. It’s full of mathematical proofs. But unless you are actually developing cryptographic systems, much of that complexity is not necessary to understand what is going on at a high level.</p>
<p>If you opened this article hoping to create the next HTTPS protocol, I’m sorry to say that pigeons won’t be enough. Otherwise, brew some coffee and enjoy the article.</p>
<h3 id="heading-alice-bob-and-pigeons">Alice, Bob and … pigeons?</h3>
<p>Any activity you do on the Internet (reading this article, buying stuff on Amazon, uploading cat pictures) comes down to sending and receiving messages to and from a server.</p>
<p>This can be a bit abstract so let’s imagine that those messages were delivered by <strong>carrier pigeons</strong>. I know that this may seem very arbitrary, but trust me HTTPS works the same way, albeit a lot faster.</p>
<p>Also instead of talking about servers, clients and hackers, we will talk about Alice, Bob and Mallory. If this isn’t your first time trying to understand cryptographic concepts you will recognize those names, because they are widely used in technical literature.</p>
<h3 id="heading-a-first-naive-communication">A first naive communication</h3>
<p>If Alice wants to send a message to Bob, she attaches the message on the carrier pigeon’s leg and sends it to Bob. Bob receives the message, reads it and it’s all is good.</p>
<p>But what if Mallory intercepted Alice’s pigeon in flight and changed the message? Bob would have no way of knowing that the message that was sent by Alice was modified in transit.</p>
<p>This is how <strong>HTTP</strong> works. Pretty scary right? I wouldn’t send my bank credentials over HTTP and neither should you.</p>
<h3 id="heading-a-secret-code">A secret code</h3>
<p>Now what if Alice and Bob are very crafty. They agree that they will write their messages using a secret code. They will shift each letter by 3 positions in the alphabet. For example D → A, E → B, F → C. The plain text message “secret message” would be “pbzobq jbppxdb”.</p>
<p>Now if Mallory intercepts the pigeon she won’t be able to change the message into something meaningful nor understand what it says, because she doesn’t know the code. But Bob can simply apply the code in reverse and decrypt the message where A → D, B → E, C → F. The cipher text “pbzobq jbppxdb” would be decrypted back to “secret message”.</p>
<p>Success!</p>
<p>This is called <strong>symmetric key cryptography</strong>, because if you know how to encrypt a message you also know how to decrypt it.</p>
<p>The code I described above is commonly known as the <strong>Caesar cipher</strong>. In real life, we use fancier and more complex codes, but the main idea is the same.</p>
<h3 id="heading-how-do-we-decide-the-key">How do we decide the key?</h3>
<p>Symmetric key cryptography is very secure if no one apart from the sender and receiver know what key was used. In the Caesar cipher, the <strong>key is an offset</strong> of how many letters we shift each letter by. In our example we used an offset of 3, but could have also used 4 or 12.</p>
<p>The issue is that if Alice and Bob don’t meet before starting to send messages with the pigeon, they would have no way to establish a key securely. If they send the key in the message itself, Mallory would intercept the message and discover the key. This would allow Mallory to then read or change the message as she wishes before and after Alice and Bob start to encrypt their messages.</p>
<p>This is the typical example of a <strong>Man in the Middle Attack</strong> and the only way to avoid it is to change the encryption system all together.</p>
<h3 id="heading-pigeons-carrying-boxes">Pigeons carrying boxes</h3>
<p>So Alice and Bob come up with an even better system. When Bob wants to send Alice a message she will follow the procedure below:</p>
<ul>
<li>Bob sends a pigeon to Alice without any message.</li>
<li>Alice sends the pigeon back carrying a box with an open lock, but keeping the key.</li>
<li>Bob puts the message in the box, closes the locks and sends the box to Alice.</li>
<li>Alice receives the box, opens it with the key and reads the message.</li>
</ul>
<p>This way Mallory can’t change the message by intercepting the pigeon, because she doesn’t have the key. The same process is followed when Alice wants to send Bob a message.</p>
<p>Alice and Bob just used what is commonly known as <strong>asymmetric key cryptography</strong>. It’s called asymmetric, because even if you can encrypt a message (lock the box) you can’t decrypt it (open a closed box).<br>In technical speech the box is known as the <strong>public key</strong> and the key to open it is known as the <strong>private key</strong>.</p>
<h3 id="heading-how-do-i-trust-the-box">How do I trust the box?</h3>
<p>If you paid attention you may have noticed that we still have a problem. When Bob receives that open box how can he be sure that it came from Alice and that Mallory didn’t intercept the pigeon and changed the box with one she has the key to?</p>
<p>Alice decides that she will sign the box, this way when Bob receives the box he checks the signature and knows that it was Alice who sent the box.</p>
<p>Some of you may be thinking, how would Bob identify Alice’s signature in the first place? Good question. Alice and Bob had this problem too, so they decided that, instead of Alice signing the box, Ted will sign the box.</p>
<p>Who is Ted? Ted is a very famous, well known and trustworthy guy. Ted gave his signature to everyone and everybody trusts that he will only sign boxes for legitimate people.</p>
<p>Ted will only sign an Alice box if he’s sure that the one asking for the signature is Alice. So Mallory cannot get an Alice box signed by Ted on behalf of her as Bob will know that the box is a fraud because Ted only signs boxes for people after verifying their identity.</p>
<p>Ted in technical terms is commonly referred to as a <strong>Certification Authority</strong> and the browser you are reading this article with comes packaged with the signatures of various Certification Authorities.</p>
<p>So when you connect to a website for the first time you trust its box because you trust Ted and Ted tells you that the box is legitimate.</p>
<h3 id="heading-boxes-are-heavy">Boxes are heavy</h3>
<p>Alice and Bob now have a reliable system to communicate, but they realize that pigeons carrying boxes are slower than the ones carrying only the message.</p>
<p>They decide that they will use the box method (asymmetric cryptography) only to choose a key to encrypt the message using symmetric cryptography with (remember the Caesar cipher?).</p>
<p>This way they get the best of both worlds. The reliability of asymmetric cryptography and the efficiency of symmetric cryptography.</p>
<p>In the real world there aren’t slow pigeons, but nonetheless encrypting messages using asymmetric cryptography is slower than using symmetric cryptography, so we only use it to exchange the encryption keys.</p>
<p>Now you know how <strong>HTTPS</strong> works and your coffee should also be ready. Go drink it you deserved it ?</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
