<?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" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[VectoScalar - Medium]]></title>
        <description><![CDATA[VectoScalar Write-ups - Medium]]></description>
        <link>https://medium.com/vectoscalar?source=rss----ecfc2f0ad21e---4</link>
        <image>
            <url>https://cdn-images-1.medium.com/proxy/1*TGH72Nnw24QL3iV9IOm4VA.png</url>
            <title>VectoScalar - Medium</title>
            <link>https://medium.com/vectoscalar?source=rss----ecfc2f0ad21e---4</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Fri, 13 Nov 2026 18:15:39 GMT</lastBuildDate>
        <atom:link href="https://medium.com/feed/vectoscalar" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Best Practices for Amazon DynamoDB in Real-Time Applications]]></title>
            <link>https://medium.com/vectoscalar/best-practices-for-amazon-dynamodb-in-real-time-applications-fd0889b293ff?source=rss----ecfc2f0ad21e---4</link>
            <guid isPermaLink="false">https://medium.com/p/fd0889b293ff</guid>
            <dc:creator><![CDATA[Siddharth Satija]]></dc:creator>
            <pubDate>Fri, 16 Feb 2024 10:19:35 GMT</pubDate>
            <atom:updated>2024-02-16T10:19:35.739Z</atom:updated>
            <content:encoded><![CDATA[<p>Amazon DynamoDB is a highly scalable, fast, and reliable NoSQL database that is well-suited for real-time use cases. However, in order to fully leverage its capabilities and achieve optimal performance, it’s important to understand and follow best practices. In this article, we’ll explore some of the best practices for using Amazon DynamoDB.</p><ol><li><strong>Choosing the Right Partition Key</strong> <br>The partition key is the most important aspect of DynamoDB performance, as it determines how data is distributed across partitions. To ensure optimal performance, it’s important to choose a partition key that is both unique and evenly distributed. In real-time use cases, it’s also important to consider the potential for data growth and ensure that the partition key will continue to be evenly distributed as the data set grows. <br>For example, let’s say you have a real-time e-commerce platform and you want to store customer data in DynamoDB. A good partition key for this use case would be the customer’s email address, as it is unique and will provide a good distribution of data across partitions.</li><li><strong>Provisioning Adequate Read and Write Capacity Units</strong> <br>DynamoDB performance is heavily dependent on the number of read and write capacity units that are provisioned. To ensure fast and consistent performance, it’s important to provision enough capacity to handle the expected traffic and to regularly monitor usage patterns to ensure that capacity remains sufficient. In real-time use cases, it’s especially important to ensure that there is sufficient capacity to handle spikes in traffic.<br>For example, during a flash sale on your e-commerce platform, there may be a sudden increase in traffic. To ensure that your DynamoDB table can handle this spike in traffic, you should provision additional read and write capacity units.</li><li><strong>Using Secondary Indexes Wisely</strong><br>DynamoDB supports secondary indexes, which can greatly improve query performance. However, it’s important to use them wisely, as they can also increase costs and slow performance if used improperly. In real-time use cases, secondary indexes can be especially useful for optimizing query performance and ensuring fast response times.<br>For example, on your e-commerce platform, you may want to be able to retrieve customer data based on their purchase history. To do this efficiently, you can create a secondary index on the purchase history field and use it to quickly retrieve relevant customer data.</li><li><strong>Avoiding Overuse of Scans</strong> <br>DynamoDB provides the ability to scan tables, but overusing scans can result in slow performance and increased costs. To avoid this, it’s important to understand when and how to use scans effectively. In real-time use cases, it’s often more efficient to use queries or secondary indexes to retrieve data, as scans can take a long time to complete and may not provide the level of performance that is needed.<br>For example, let’s say you want to retrieve all customer data from your e-commerce platform. Instead of using a scan, which would be slow and inefficient, you can use a query with the partition key and sort key to retrieve the data more quickly and efficiently.</li><li><strong>Batch Writing and Reading</strong> <br>DynamoDB provides the ability to batch write and read items, which can greatly improve performance and reduce costs. In real-time use cases, it’s important to take advantage of batch operations whenever possible to ensure fast and efficient data access.<br>For example, when processing customer orders on your e-commerce platform, you can use batch write operations to efficiently store multiple orders.</li></ol><p>In conclusion, by choosing the right partition key, provisioning adequate read and write capacity units, using secondary indexes wisely, avoiding overuse of scans, and batch writing and reading, you can ensure that your real-time applications are fast, efficient, and reliable. By taking these steps, you can fully leverage the capabilities of Amazon DynamoDB and achieve the best possible performance and results for your real-time applications.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=fd0889b293ff" width="1" height="1" alt=""><hr><p><a href="https://medium.com/vectoscalar/best-practices-for-amazon-dynamodb-in-real-time-applications-fd0889b293ff">Best Practices for Amazon DynamoDB in Real-Time Applications</a> was originally published in <a href="https://medium.com/vectoscalar">VectoScalar</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Closer look at Closures.]]></title>
            <link>https://medium.com/vectoscalar/closer-look-at-closures-e23f74eb36a5?source=rss----ecfc2f0ad21e---4</link>
            <guid isPermaLink="false">https://medium.com/p/e23f74eb36a5</guid>
            <category><![CDATA[javascript-tips]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[advanced-javascript]]></category>
            <category><![CDATA[closures-functions]]></category>
            <dc:creator><![CDATA[Anup Verma]]></dc:creator>
            <pubDate>Mon, 05 Feb 2024 13:23:22 GMT</pubDate>
            <atom:updated>2024-02-05T13:23:22.817Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*RM7_A5CzcTNcymCMGIFK6w.jpeg" /></figure><blockquote>‘closure’ is the combination of a function bundled together with references to its surrounding state (<strong>Lexical Environment</strong>).</blockquote><p>Before we move any further , few things to be aware in order to understand Closures are :-</p><p>1- Execution Context</p><p>2- Call Stack</p><p>3- Scope Chain</p><h3><strong>The Execution Context.</strong></h3><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fgiphy.com%2Fembed%2F8zoGaqY9JcOQskXiyu%2Ftwitter%2Fiframe&amp;display_name=Giphy&amp;url=https%3A%2F%2Fgiphy.com%2Fgifs%2Fcbs-the-neighborhood-theneighborhood-sheaun-mckinney-8zoGaqY9JcOQskXiyu&amp;image=https%3A%2F%2Fmedia4.giphy.com%2Fmedia%2Fv1.Y2lkPTc5MGI3NjExNmtudGZnMmljM2V1MTByZTE0Znk1aGJ5OWZiNjUxcDF3OW10a3draSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw%2F8zoGaqY9JcOQskXiyu%2Fgiphy.gif&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=giphy" width="435" height="243" frameborder="0" scrolling="no"><a href="https://medium.com/media/d43025a9e8cc1685887812fd29c48931/href">https://medium.com/media/d43025a9e8cc1685887812fd29c48931/href</a></iframe><p>There are two types of Execution Context :-</p><p>1- Global Execution Context (Global EC )</p><p>2- Local Execution Context (Local EC )</p><pre>const name = &#39;Anup Verma&#39;<br>function callMe(a,b){<br>let x = 5;<br>  console.log(&#39;params :: &#39;,a,b,&#39;name :: &#39;,name ,&#39;x :: &#39;,x);<br>}<br>callMe(2,3);</pre><p>Global and Local E.C for the above snippet would look like:-</p><figure><img alt="global execution context and local execution context in play" src="https://cdn-images-1.medium.com/max/1024/1*8fAPI_QuFE3xzaTibX1EsA.png" /><figcaption>Global and Local E.C in action</figcaption></figure><p>NOTE :</p><p>The Local E.C of a function contains information regarding its “<strong><em>Arguments”</em></strong>, “<strong><em>this”</em></strong> keyword and “<strong><em>variables”</em></strong> declared inside it.</p><blockquote>But , in case of an <strong>Arrow Function</strong> and <strong>Anonymous function</strong> , ‘<strong>this’ <em>keyword and</em> ‘Arguments’ <em>are NOT present</em>.</strong></blockquote><h3>The Call Stack.</h3><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fgiphy.com%2Fembed%2FxT3i0MGfzfEo54bh60%2Ftwitter%2Fiframe&amp;display_name=Giphy&amp;url=https%3A%2F%2Fgiphy.com%2Fgifs%2Fshowtimesports-episode-1-xT3i0MGfzfEo54bh60&amp;image=https%3A%2F%2Fmedia3.giphy.com%2Fmedia%2Fv1.Y2lkPTc5MGI3NjExbG05OG9sdXd6Zm40Yzg3bmM1N29ucTNuN24wamFtaGNxZ25ub2MzaSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw%2FxT3i0MGfzfEo54bh60%2Fgiphy.gif&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=giphy" width="435" height="244" frameborder="0" scrolling="no"><a href="https://medium.com/media/06f2a647b195d99bf6cb1d90e8462ac5/href">https://medium.com/media/06f2a647b195d99bf6cb1d90e8462ac5/href</a></iframe><p>The place where all the Magic Happens.</p><p>The call stack is where each and every <strong><em>execution context is placed</em></strong> in a form of a stack and is executed and “<strong><em>popped out”</em></strong> once it is done executing.</p><p><em>Consider the following example.</em></p><pre>const counting = function(){<br>  let count = 0; <br>  return function(){<br>      count++;<br>      console.log(&#39;count :: &#39;, count);<br>  }<br>}<br>const counter = counting();<br><br>counter(); //count :: 1<br>counter(); //count :: 2<br>counter(); //count :: 3</pre><p><em>The Call Stack and the Execution contexts working together.</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*OgwfJLJc3dJt7EzPFKjWdA.png" /><figcaption><strong>Call stack when counting is executing</strong></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*WMtXLEhRyaUazdWxtLnNCQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YaUj5zGIiHpn4Y5BoBUV1A.png" /><figcaption><strong>Left : After counting has finished executing , it is popped off from the Call Stack</strong></figcaption></figure><blockquote>As you can see from the bottom two images , even though the <strong><em>counting</em></strong> function is no more present in the call stack , then too the “<strong><em>counter function”</em></strong> has the access to the variables in the Environment in which it was created <br><strong>(i.e counting()).</strong></blockquote><h3><strong>Closures.</strong></h3><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fgiphy.com%2Fembed%2FeMsCxr6w35vjfI4zl5%2Ftwitter%2Fiframe&amp;display_name=Giphy&amp;url=https%3A%2F%2Fgiphy.com%2Fgifs%2FFriends-season-2-episode-7-closure-eMsCxr6w35vjfI4zl5&amp;image=https%3A%2F%2Fmedia1.giphy.com%2Fmedia%2FeMsCxr6w35vjfI4zl5%2Fgiphy.gif%3Fcid%3D790b7611bcfe71422c0705cc8e0b5c229bc43f47f2199f15%26rid%3Dgiphy.gif%26ct%3Dg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=giphy" width="435" height="362" frameborder="0" scrolling="no"><a href="https://medium.com/media/8fc3c05843503608cb60f1299a06eb91/href">https://medium.com/media/8fc3c05843503608cb60f1299a06eb91/href</a></iframe><p>Any function always has the access to the variable environments of the <strong>Execution Context </strong>in which the function was created , Even after that Execution context is <strong>Gone</strong>.</p><blockquote>“C<strong>ounter()</strong>” function was born in the <strong><em>Execution context of ‘Counting()’</em></strong> function , hence this ‘Counter()’ function will get access to the variable environment (i.e “<strong><em>count” </em></strong><em>)</em></blockquote><h3>WHAT is Closure ?</h3><blockquote>Closure is this <strong><em>Variable Environment</em></strong> Attached to the function , exactly as it was at the time and place when the function was created and the scope chain is ‘Preserved’ through this closure.</blockquote><p>Thanks to this ‘<strong>closure</strong>’ a function <strong><em>does not lose connection</em></strong> to variables that existed at the function’s birth place.</p><p>Although this is one of those topics which people tend to forget , here are some intuitive examples/analogies to help you understand what closures are all about.</p><h3><strong>Informal Definition(s)</strong></h3><blockquote>A closure gives a function ‘<strong><em>Access</em></strong>’ to all the variables of its <strong>parent function</strong> , even after the parent function has <strong><em>returned</em></strong>. The function keeps a “<strong><em>reference” </em></strong>to its outer <strong>SCOPE , </strong>which “<strong><em>preserves” </em></strong>the scope chain throughout.</blockquote><p>It’s like a person who doesn’t lose connection to their HOME-TOWN , in this analogy,<br>Person -&gt; Function <br>Home town -&gt; Parent Scope</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/612/1*4j5GHUzJmcP0-OcnmrKv1Q.jpeg" /></figure><blockquote><strong>PERSON</strong> — — —&gt; <strong>Connection</strong> — — —&gt; <strong>HOME-TOWN</strong>( — — →<strong>Variables</strong>)</blockquote><p>And the person does not lose connection to the variables stored in its parent scope i.e home town.</p><h3>CONCLUSION</h3><p>We <strong>don’t</strong> have to create “closures” <strong>Manually</strong>, this is something JavaScript does completely<strong> Automatically, </strong>also there is <strong>no way</strong> we can access these ‘closed-over’ variables explicitly i.e <em>because “A Closure is </em><strong><em>NOT </em></strong><em>a tangible JavaScript Object.”</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e23f74eb36a5" width="1" height="1" alt=""><hr><p><a href="https://medium.com/vectoscalar/closer-look-at-closures-e23f74eb36a5">Closer look at Closures.</a> was originally published in <a href="https://medium.com/vectoscalar">VectoScalar</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Sending SES Email With An Attachment Using Mailcomposer]]></title>
            <link>https://medium.com/vectoscalar/sending-ses-email-with-an-attachment-using-mailcomposer-94d2ab787034?source=rss----ecfc2f0ad21e---4</link>
            <guid isPermaLink="false">https://medium.com/p/94d2ab787034</guid>
            <dc:creator><![CDATA[Ankita]]></dc:creator>
            <pubDate>Thu, 01 Feb 2024 07:17:58 GMT</pubDate>
            <atom:updated>2024-02-01T07:17:58.140Z</atom:updated>
            <content:encoded><![CDATA[<p><strong>Amazon Simple Email Service(SES)</strong> is a cloud email service provider that can integrate into any application for sending emails.</p><p>We can use the <strong>sendRawEmail</strong> method of SES to send emails with attachments. This method accepts only <strong>Multipurpose Internet Mail Extensions standard (MIME)</strong> type data as email content. Creating a MIME message yourself is a tedious task . But we can do this easily using mailcomposer package.</p><p>In this article we will see how we can send email with excel file as an attachment using mailcomposer.</p><p><strong>Prerequisite for sending email using SES:</strong></p><p>We can only send emails from and to verified email addresses or domains. We can verify any email address on AWS SES console by following the steps below:</p><p><strong>STEP 1:</strong> Go to the <strong>AWS SES</strong> console and click <strong>Verified identities</strong> option.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*PNW_PoxAIF1lLW-xYNrx1A.png" /></figure><p><strong>STEP 2: </strong>Click on <strong>Create Identity</strong> option to create identity of your email address.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*mKL0iProXkSzXDnYbybyJw.png" /></figure><p><strong>STEP 3:</strong> Select <strong>Email Address</strong> option in identity type to verify a particular email address . Then enter your email address and click on <strong>Create identity</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YZ5dYj1Eo4-a1_tbv2IHDA.png" /></figure><p><strong>Step 4:</strong> Now click on the verification link sent on your email address to complete verification. Now you can see your email address is going to be displayed with identity status as ‘verified’ under verified identities on console.</p><p><strong>Setup nodeJs app:</strong></p><p>Now we will set up our node application</p><p>Run following commands in terminal:</p><blockquote><strong>npm init -y</strong></blockquote><blockquote><strong>npm i aws-sdk</strong></blockquote><blockquote><strong>npm i xlsx</strong></blockquote><blockquote><strong>npm i mailcomposer</strong></blockquote><p><strong>aws-sdk</strong> — for calling SES sendRawEmail function</p><p><strong>xlsx</strong> — for converting array of objects into excel file buffer</p><p><strong>mailcomposer</strong> -for creating a MIME message for email</p><p>Create <strong>index.js</strong> file . This will be the main file where we write all our code.</p><p>Paste the below code in <strong>index.js</strong> file.</p><pre>(async()=&gt;{<br><br>const AWS = require(&#39;aws-sdk&#39;);<br>const XLSX = require(&#39;xlsx&#39;);<br>const mailcomposer= require(&#39;mailcomposer&#39;);<br><br>//create ses client with your AWS account access key id and secret access key<br>const sesClient = new AWS.SES({<br>    accessKeyId: YOUR_ACCESS_KEY_ID,<br>    secretAccessKey: YOUR_SECRET_ACCESS_KEY,<br>    region: &quot;ap-south-1&quot;<br>});<br><br>/**<br>    * To create excel file buffer from array of objects<br>    * @param {*} data    : [[], []] : For multiple sheets    [[]]: for single sheet <br>    * @param {*} sheetNames : [&#39;sheet1&#39;, &#39;sheet2&#39;] names of sheet<br>    * @returns <br>*/<br>const createExcelFileBufferUsingXlsx = (data,sheetNames)=&gt;{<br>    <br>    const wb = XLSX.utils.book_new();                    <br>    if(Array.isArray(data) &amp;&amp; data.length &amp;&amp; Array.isArray(data[0])) {<br>        data.forEach((dataArray, idx) =&gt; {<br>            const ws = XLSX.utils.json_to_sheet(dataArray);            <br>            XLSX.utils.book_append_sheet(wb, ws, sheetNames[idx]);  <br>        })<br>    } <br><br>    //creating buffer<br>    const wbOpts = { bookType: &quot;xlsx&quot;, type: &quot;buffer&quot; };<br>    let fileBufferdata = XLSX.write(wb, wbOpts);<br><br>    console.info(&#39;fileBufferdata::&#39;, fileBufferdata);<br><br>    return fileBufferdata;<br>    <br>}<br><br>/**<br> * To send email with attachment using mailcomposer<br> * @param {*} sourceEmail <br> * @param {*} receiverEmail <br> * @param {*} fileBufferdata <br> * @returns <br> */<br>const sendRawEmailUsingMailcompose = async(sourceEmail,receiverEmail,fileBufferdata)=&gt;{<br>    let sendRawEmailPromise ={};<br><br>    //creating object with mentioned options<br>    const mail = mailcomposer({<br>        from: sourceEmail,        //source email address<br>        to: [receiverEmail],      //array containing receiver’s email addresses<br>        subject:&#39;Test mail&#39;,      //subject of email<br>        text: &#39;PFA excel file&#39;,   //plain text to display in mail body<br>        attachments: [{           //array of attachment object having below details<br>            filename: &quot;test.xlsx&quot;,   //name of attachment<br>            content: fileBufferdata.toString(&#39;base64&#39;).replace(/([^\0]{76})/g, &quot;$1\n&quot;), // buffered file data as base64 encoded<br>            encoding: &#39;base64&#39;, //encoding type<br>        }],<br>      });<br><br>    console.info(&quot;mail&quot;, mail);<br>    <br>    return new Promise((resolve, reject) =&gt; {<br>        //building message to send in email<br>        mail.build((err, message) =&gt; {<br>          if (err) {<br>            reject(`Error sending raw email: ${err}`);<br>          }<br>          console.info(&quot;inside mail build&quot;);<br><br>          //sending email after attaching excel file<br>            sendRawEmailPromise = sesClient.sendRawEmail({RawMessage: {Data: message}}).promise();<br>            resolve(sendRawEmailPromise);<br>        });<br>        <br>    });<br><br>    <br>}<br><br>const sendSesEmail=async()=&gt; {<br>    try {<br>       <br>        const sourceEmail= &quot;abc@gmail.com&quot;;<br>        const receiverEmail= &quot;xyz@gmail.com&quot;;<br><br>        const data= [<br>            {name:&quot;user1&quot;, roll_no:1},<br>            {name:&quot;user2&quot;, roll_no:2}<br>        ]<br><br>        console.info(&quot;sourceEmail, receiverEmail&quot;, sourceEmail, receiverEmail);<br>        console.info(&quot;data&quot;, data);<br><br>        const fileBufferdata= createExcelFileBufferUsingXlsx([data],[&quot;sheet1&quot;]);<br>        <br>        const sesResponse =await sendRawEmailUsingMailcompose(sourceEmail, receiverEmail,fileBufferdata);<br>         <br>        console.info(&quot;sesResponse&quot;,sesResponse);<br>    } catch (error) {<br>        console.error(error);<br>    }<br>}<br><br>await sendSesEmail()<br>})();</pre><p><strong>Code Flow:</strong></p><ol><li>Firstly we have imported all required packages.</li><li>Then we have created an object of the SES service using aws-sdk. Here replace <strong>YOUR_ACCESS_KEY_ID</strong> and <strong>YOUR_SECRET_ACCESS_KEY</strong> with your aws account key id and secret access key in code.</li><li><strong>sendSesEmail</strong> is our main function where all are processing will be done.</li><li>In this function we have first declared sourceEmail(verified email address from which we will send email) and receiverEmail(verified email address to which we will send email).</li><li>Then we have defined array of object which we will show in excel file.</li><li>After that we have called <strong>createExcelFileBufferUsingXlsx</strong> function which is using the xlsx package to convert our array of objects into an excel file buffer. We have passed array of objects and sheet name in argument.</li><li>In this function, <strong>json_to_sheet()</strong> — will convert array of objects into worksheet, <strong>book_new() </strong>— will create a new workbook in a sheet , <strong>book_append_sheet()</strong> — will append the worksheet to the workbook with sheet name passed in arguments (i.e sheet1) and <strong>write() </strong>— will convert the created excel file into buffer.</li><li>Then we have passed buffer data, source and receiver email in <strong>sendRawEmailUsingMailcomposer</strong> function. This function is where we will create our email body using mailcomposer and call the sesRawEmail function to send email.</li><li>Here we have first created a object of mailcomposer with options.</li><li>Then we built a mail message using the build function of mailcomposer and passed that message to the <strong>sendRawEmail</strong> function of SES service which will send the email.</li></ol><p>That’s it, now we can run above code using <strong>node index.js</strong> command. This will send the email with the attached excel file to the receiver. You can see the email sent using the above code in below images.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*x6pht6tva1hWFF6ckgTqMA.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*nn6q7m1W1AdGh4gTL3HHlg.png" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=94d2ab787034" width="1" height="1" alt=""><hr><p><a href="https://medium.com/vectoscalar/sending-ses-email-with-an-attachment-using-mailcomposer-94d2ab787034">Sending SES Email With An Attachment Using Mailcomposer</a> was originally published in <a href="https://medium.com/vectoscalar">VectoScalar</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Recursive AWS Lambda Functions: An Overview]]></title>
            <link>https://medium.com/vectoscalar/recursive-aws-lambda-functions-an-overview-2cf3b361c6ef?source=rss----ecfc2f0ad21e---4</link>
            <guid isPermaLink="false">https://medium.com/p/2cf3b361c6ef</guid>
            <dc:creator><![CDATA[Siddharth Satija]]></dc:creator>
            <pubDate>Mon, 22 Jan 2024 04:53:32 GMT</pubDate>
            <atom:updated>2024-01-22T04:53:32.679Z</atom:updated>
            <content:encoded><![CDATA[<p>AWS Lambda is a popular serverless compute service that allows you to run code in response to a variety of events, such as changes to data in an Amazon S3 bucket or a message arriving in an Amazon Kinesis stream. In this article, we’ll focus on a specific type of Lambda function: recursive functions.</p><h3>Setting Up a Recursive AWS Lambda Function</h3><p>To set up a recursive AWS Lambda function, you’ll need to follow these steps:</p><ol><li>Create a new Lambda function or use an existing one</li><li>Configure the function to trigger itself as an event</li><li>Include a termination condition to stop the recursion</li></ol><p>Let’s take a closer look at each of these steps.</p><h3>Step 1: Create a New Lambda Function</h3><p>To create a new Lambda function, log in to the AWS Management Console and navigate to the Lambda dashboard. From there, click the “Create function” button to start the function creation process.</p><p>Follow the prompts to choose a runtime and select a blueprint (if desired). For the purposes of this article, we’ll assume you’re using Node.js as the runtime.</p><h3>Step 2: Configure the Function to Trigger Itself</h3><p>Next, you’ll need to configure the function to trigger itself as an event. To do this, you’ll need to create a new trigger and specify the function as the target.</p><p>For example, let’s say you want the function to trigger itself every time a new item is added to an Amazon DynamoDB table. You would create a DynamoDB trigger and specify your function as the target.</p><h3>Step 3: Include a Termination Condition</h3><p>It’s important to include a termination condition in your recursive Lambda function, as this will prevent the function from triggering itself indefinitely.<br>For example, the following code demonstrates how to implement a termination condition in a Node.js recursive Lambda function</p><pre>const AWS = require(&#39;aws-sdk&#39;);<br><br>exports.handler = async (event, context, callback) =&gt; {<br>  try {<br>    // Initialize the DynamoDB client<br>    const dynamoDb = new AWS.DynamoDB.DocumentClient();<br><br>    // Define the parameters for the query<br>    const params = {<br>      TableName: &#39;records&#39;,<br>      Limit: 100,<br>      ExclusiveStartKey: event.lastEvaluatedKey<br>    };<br><br>    // Query the DynamoDB table for the next batch of records<br>    const data = await dynamoDb.scan(params).promise();<br><br>    // Process the records<br>    const processedRecords = data.Items.map(processRecord);<br><br>    // Check if there are more records to process<br>    if (!data.LastEvaluatedKey) {<br>      // If there are no more records, return the processed records<br>      return callback(null, processedRecords);<br>    }<br><br>    // Set the last evaluated key for the next iteration<br>    event.lastEvaluatedKey = data.LastEvaluatedKey;<br><br>    // Trigger the function again, passing the updated event data<br>    const result = await context.function.invoke(event);<br><br>    // Return the result<br>    callback(null, [...processedRecords, ...result]);<br>  } catch (error){<br>    console.log(&quot;error&quot;,error)<br>   }</pre><p>This function queries a DynamoDB table named “records” in chunks of 100 items at a time, using the scan operation and the Limit and ExclusiveStartKey parameters. It processes the records using the processRecord function and stores the results in an array. The function triggers itself until there are no more records to process, as indicated by the absence of a LastEvaluatedKey in the query result. The function returns the processed records when there are no more records to process.</p><h3>Handling Errors and Exceptions in Recursive Lambda Functions</h3><p>As with any type of software, it’s important to handle errors and exceptions in your recursive Lambda functions to ensure that they run smoothly and don’t fail unexpectedly.</p><p>Here are a few best practices for handling errors and exceptions in recursive Lambda functions:</p><ol><li>Use try/catch blocks to handle exceptions that may occur within the function body</li><li>Use the function callback to return errors or exceptions to the caller</li><li>Consider setting up an error reporting system, such as AWS CloudWatch</li></ol><h3><strong>Summary</strong></h3><p>Setting up a recursive AWS Lambda function involves creating a new function, configuring the function to trigger itself as an event, and including a termination condition to stop the recursion. By following these steps and properly handling errors and exceptions, you can use recursive Lambda functions to process large datasets and perform complex operations in a cost-effective, scalable, and serverless way.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2cf3b361c6ef" width="1" height="1" alt=""><hr><p><a href="https://medium.com/vectoscalar/recursive-aws-lambda-functions-an-overview-2cf3b361c6ef">Recursive AWS Lambda Functions: An Overview</a> was originally published in <a href="https://medium.com/vectoscalar">VectoScalar</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to fix the lambda package size limit exceeded error caused by python libraries]]></title>
            <link>https://medium.com/vectoscalar/how-to-fix-the-lambda-package-size-limit-exceeded-error-caused-by-python-libraries-f66e1096830b?source=rss----ecfc2f0ad21e---4</link>
            <guid isPermaLink="false">https://medium.com/p/f66e1096830b</guid>
            <dc:creator><![CDATA[Akshika Choudhary]]></dc:creator>
            <pubDate>Mon, 15 Jan 2024 05:43:45 GMT</pubDate>
            <atom:updated>2024-01-15T05:43:45.093Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/683/1*fzch1gQIfBH04-wDyRq9Tw.jpeg" /><figcaption>Python package deployment to AWS lambda</figcaption></figure><p>I’m using the K-means clustering algorithm to create a recommendation engine for an ecommerce application. As a result, I needed the Scikit-learn and pandas libraries, which increased the size of my deployment package beyond the AWS lambda package limits.</p><p>During the deployment of my stack I got this error:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Wbfyk8u5iZGlRE_qpPHBRw.png" /><figcaption>Package Size limit exceeded</figcaption></figure><h3>Deployment Package Limits</h3><p>When developing a serverless application, you should keep some soft and hard limits in mind for each AWS service. These restrictions are intended to protect both the customer and the provider from unintentional use. In addition, guardrails are provided to ensure that best practises are followed.<br>AWS Lambda has a hard limit of 50MB for compressed deployment packages and a hard limit of 250MB for uncompressed deployment packages.</p><h3><strong>How to deal with size limits when we are using libraries like scikit-learn, pandas etc?</strong></h3><p>To help with managing potentially large dependencies, functionality for compressing libraries is available (for example: pandas, numpy, scipy, and scikit-learn). To decompress them, you’ll need to make some changes to your code.</p><p>Firstly add the following configuration to your serverless.yml file.</p><pre>custom:<br>  pythonRequirements:<br>    zip: true</pre><p>Then add this piece of code to the beginning of our handler module in your handler.py file.</p><pre>try:<br>  import unzip_requirements<br>except ImportError:<br>  pass</pre><blockquote>Note: Handler function in handler.py is the entry point of any lambda function. It is the first function that is executed when your lambda function is invoked.</blockquote><p>These modification in your code resolve your issue of package size limit exceeded.</p><h4><strong>A Lambda Layer is another option for dealing with large dependencies.</strong></h4><p>For this include the layer option in your configuration in serverless.yml file.</p><pre>custom:<br>  pythonRequirements:<br>    layer: true</pre><p>A layer will be automatically produced after the requirements are compressed into a zip file. The reference must be added to the functions that will use the layer.</p><p>Add this reference to the function define in serverless.yml file.</p><pre>functions:<br>  myfunction:<br>    handler: handler.myfunctions<br>    layers:<br>      - Ref: PythonRequirementsLambdaLayer</pre><p>You can also add this custom configuration into your layer in serveless.yml file :</p><pre>custom:<br>  pythonRequirements:<br>    layer:<br>      name: ${self:provider.stage}-layerName<br>      description: lambda layer for python requirements<br>      compatibleRuntimes:<br>        - python3.8<br>      licenseInfo: GPLv3<br>      allowedAccounts:<br>        - &#39;*&#39;</pre><blockquote>Key Note: We can also use theImage package type, which has a much larger file size limitation but it requires more configuration as compared to above mentioned methods.</blockquote><p>We all know that when we build a machine learning model the algorithms which we use consist of high packages libraries. So, to overcome the lambda package size limit while deploying these model we can use the above approaches.</p><p>Keep Learning Keep Growing 🥂</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f66e1096830b" width="1" height="1" alt=""><hr><p><a href="https://medium.com/vectoscalar/how-to-fix-the-lambda-package-size-limit-exceeded-error-caused-by-python-libraries-f66e1096830b">How to fix the lambda package size limit exceeded error caused by python libraries</a> was originally published in <a href="https://medium.com/vectoscalar">VectoScalar</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Cashfree SDK integration in React Native App]]></title>
            <link>https://medium.com/vectoscalar/cashfree-sdk-integration-in-react-native-app-cba7fa9f2b2?source=rss----ecfc2f0ad21e---4</link>
            <guid isPermaLink="false">https://medium.com/p/cba7fa9f2b2</guid>
            <category><![CDATA[frontend]]></category>
            <category><![CDATA[payment-integration]]></category>
            <category><![CDATA[mobile-app-development]]></category>
            <category><![CDATA[react-native]]></category>
            <category><![CDATA[cashfree-payment]]></category>
            <dc:creator><![CDATA[Ashish Semwal]]></dc:creator>
            <pubDate>Mon, 08 Jan 2024 05:30:26 GMT</pubDate>
            <atom:updated>2024-01-08T05:30:26.235Z</atom:updated>
            <content:encoded><![CDATA[<p>Hello Everyone In this article we will learn how to integrate Cashfree payments SDK in React Native Application.</p><h4>The React Native Cashfree SDK</h4><p>Cashfree provides a dedicated SDK for React Native. The Cashfree React Native SDK allows us to integrate Cashfree Payment Gateway into our application and start collecting payments from our customers. The React Native SDK has been designed to minimise the complexity of handling and integrating payments in your React Native project.</p><p>It’s very easy to integrate Cashfree payments into our React Native Application and can be done in few steps.</p><h4>Before we get to the SDK Integration first we have to create a free Cashfree account.</h4><h4>Create Account.</h4><p>To create a account go to the <a href="https://www.cashfree.com/">Cashfree Payments website</a> and click Create Account and fill all the required fields.<br>Once the account has been created we will have the access to the test and production environments in which we can simulate multiple features of the Cashfree Payments.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*gnXh46c574sFSlTtyU0BsQ.png" /><figcaption>Sign Up Cashfree</figcaption></figure><p>After Creating account you will have the option to activate your account you can choose to activate it later and explore the test environment.<br>Note: To use the production environment we have to activate our account.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*hDHf5UD6LwXfJfVE5cQ3Pg.png" /><figcaption>Test Environment Dashboard</figcaption></figure><h3>Once the account is created then Integration can be done in 4 easy steps:</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*A-7q-BxHgR8U7l6Pab4xRQ.png" /><figcaption>Flow of payments</figcaption></figure><h4>1. Installing the SDK</h4><p>The SDK can be installed easily just navigate to your project folder and run “npm install react-native-cashfree-pg-sdk” command.<br>Once the installation is complete then open “info.plist” file inside project’s ios folder and add the following code.</p><pre>&lt;key&gt;LSApplicationCategoryType&lt;/key&gt;<br>&lt;string&gt;&lt;/string&gt;<br>&lt;key&gt;LSApplicationQueriesSchemes&lt;/key&gt;<br>&lt;array&gt;<br>&lt;string&gt;phonepe&lt;/string&gt;<br>&lt;string&gt;tez&lt;/string&gt;<br>&lt;string&gt;paytmmp&lt;/string&gt;<br>&lt;string&gt;bhim&lt;/string&gt;<br>&lt;/array&gt;</pre><p>After adding the above code update pods by running following command<br>cd ios <br>pod install — repo-update</p><h4>2. Create an order</h4><p>Next step is to create the order for any payment merchant has to create an order. The order creation should be done from backend due to security reasons.</p><p>Cashfree provides 2 API for order creation <br>1. For production: <a href="https://api.cashfree.com/pg/orders">https://api.cashfree.com/pg/orders</a><br>2. For Testing: <a href="https://sandbox.cashfree.com/pg/orders">https://sandbox.cashfree.com/pg/orders</a></p><p>Request:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*_nMQETwCiHLCA5Eybw1eMg.png" /><figcaption>Request body for create order api</figcaption></figure><p>Note: Client secret key and APP id mentioned above can be obtained from “<a href="https://merchant.cashfree.com/merchants/pg/developers/api-keys?env=test">https://merchant.cashfree.com/merchants/pg/developers/api-keys?env=test</a>” link.</p><p>Response Body</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*HQToVdIbRsSQvHmY2MQmUQ.png" /><figcaption>Response of Cashfree create order api</figcaption></figure><p>If the order creation is successful we will get the 200 response and all the relevant order details.<br>We will save payments_session_id, order_token, cf_order_id and order_status at our end .<br>The “payment_session_id” is sent to the SDK for initiating payment as it contains all the necessary order details.</p><h4>3. Initiate Payment- Drop Flow</h4><p>Drop flow is the standard flow used by Cashfree for payments it handles all the Buisness logic and the UI components so that the payments can be done smoothly.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Zq-2DU7fYQIHmeGnJ7qFEg.png" /><figcaption>Drop Flow</figcaption></figure><p>Next Step is to initiate the payment.<br>To initiate the Drop Checkout in the SDK follow the following steps.</p><ul><li>Create a CFSession object.</li><li>Create a CFPaymentComponents object.</li><li>Create a CFTheme object.</li><li>Create a Drop Checkout Payment object.</li><li>Set payment callback.</li><li>Initiate the payment using the payment object created above</li></ul><ol><li>Create a CFSession object<br>The SDK exposes a class CFSession class which accepts payments_session_id which we got in the response of order creation API.</li></ol><pre>import {<br>  CFEnvironment,<br>  CFSession,<br>} from &#39;cashfree-pg-api-contract&#39;;<br><br>try {<br>      const session = new CFSession(<br>        &#39;payment_session_id&#39;,<br>        &#39;order_id&#39;,<br>        CFEnvironment.SANDBOX<br>      );<br>        } catch (e: any) {<br>      console.log(e.message);<br>        }</pre><p>The values for environment can only be SANDBOX and PRODUCTION. <br>SANDBOX for testing and PRODUCTION for production environment<br>Specify the Environment and pass payment_session_id and order_id received from the create order api response.</p><p>2. Create Payments components object<br>This object specifies payments mode which we want to show to our customers</p><pre>const paymentModes = new CFPaymentComponentBuilder()<br>        .add(CFPaymentModes.CARD)<br>        .add(CFPaymentModes.UPI)<br>        .add(CFPaymentModes.NB)<br>        .add(CFPaymentModes.WALLET)<br>        .add(CFPaymentModes.PAY_LATER)<br>        .build();</pre><p>3. Set a Theme <br>The CFThemeBuilder class used to create CFTheme used to set the theming for Drop checkout screen.</p><pre>const theme = new CFThemeBuilder()<br>        .setNavigationBarBackgroundColor(&#39;#E64A19&#39;)<br>        .setNavigationBarTextColor(&#39;#FFFFFF&#39;)<br>        .setButtonBackgroundColor(&#39;#FFC107&#39;)<br>        .setButtonTextColor(&#39;#FFFFFF&#39;)<br>        .setPrimaryTextColor(&#39;#212121&#39;)<br>        .setSecondaryTextColor(&#39;#757575&#39;)<br>        .build();</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/460/1*rNQdOMcKyIno6fKPdJ5DrQ.png" /><figcaption>Theme Options</figcaption></figure><p>4. Create a Drop Checkout Payment object</p><p>Use below code snippet for creating payment object for Drop Checkout</p><pre>try {<br>  const dropPayment = new CFDropCheckoutPayment(<br>        session,<br>        paymentModes,<br>        theme<br>      );<br>    CFPaymentGatewayService.doPayment(dropPayment);<br>    } catch (e: any) {<br>        console.log(e.message);<br>    }</pre><p>5. Setup Payment Callback<br>The SDK provides an interface CFCallback to receive callbacks from the SDK once the payment flow ends.</p><p>This protocol comprises of 2 methods:</p><ol><li>public void onVerify(String orderID)</li><li>public void onError(CFErrorResponse cfErrorResponse, String orderID)</li></ol><p>Code snippet demonstrating it’s usage:</p><pre>import {<br>  CFErrorResponse,<br>  CFPaymentGatewayService,<br>} from &#39;react-native-cashfree-pg-sdk&#39;;<br><br>const App = () =&gt;{<br><br>useEffect(() =&gt; {<br>    CFPaymentGatewayService.setCallback({<br>      onVerify(orderID: string): void {<br>        console.log(&#39;success &#39;, orderID);<br>        mstStore.cartStore.emptyCart(mstStore.otpStore.userId);<br>        navigation.navigate(NAVIGATION.PaymentSuccess);<br>      },<br>      onError(error: CFErrorResponse, orderID: string): void {<br>        console.log(&#39;failed &#39;, orderID);<br>        navigation.navigate(NAVIGATION.PaymentFailed);<br>      },<br>    });<br>    return () =&gt; CFPaymentGatewayService.removeCallback();<br>  }, []);<br>}</pre><p>Now Combine all of the code above and its done follow the following code snippet .</p><pre>import {<br>  CFErrorResponse,<br>  CFPaymentGatewayService,<br>} from &#39;react-native-cashfree-pg-sdk&#39;;<br><br>const App = () =&gt;{<br><br>useEffect(() =&gt; {<br>    CFPaymentGatewayService.setCallback({<br>      onVerify(orderID: string): void {<br>        console.log(&#39;success &#39;, orderID);<br>        mstStore.cartStore.emptyCart(mstStore.otpStore.userId);<br>        navigation.navigate(NAVIGATION.PaymentSuccess);<br>      },<br>      onError(error: CFErrorResponse, orderID: string): void {<br>        console.log(&#39;failed &#39;, orderID);<br>        navigation.navigate(NAVIGATION.PaymentFailed);<br>      },<br>    });<br>    return () =&gt; CFPaymentGatewayService.removeCallback();<br>  }, []);<br><br>const  startCheckout = () =&gt; {<br>    try {<br>      const session = new CFSession(<br>        &#39;payment_session_id&#39;,<br>        &#39;order_id&#39;,<br>        CFEnvironment.SANDBOX<br>      );<br>      const paymentModes = new CFPaymentComponentBuilder()<br>        .add(CFPaymentModes.CARD)<br>        .add(CFPaymentModes.UPI)<br>        .add(CFPaymentModes.NB)<br>        .add(CFPaymentModes.WALLET)<br>        .add(CFPaymentModes.PAY_LATER)<br>        .build();<br>      const theme = new CFThemeBuilder()<br>        .setNavigationBarBackgroundColor(&#39;#E64A19&#39;)<br>        .setNavigationBarTextColor(&#39;#FFFFFF&#39;)<br>        .setButtonBackgroundColor(&#39;#FFC107&#39;)<br>        .setButtonTextColor(&#39;#FFFFFF&#39;)<br>        .setPrimaryTextColor(&#39;#212121&#39;)<br>        .setSecondaryTextColor(&#39;#757575&#39;)<br>        .build();<br>      const dropPayment = new CFDropCheckoutPayment(<br>        session,<br>        paymentModes,<br>        theme<br>      );<br>      CFPaymentGatewayService.doPayment(dropPayment);<br>    } catch (e: any) {<br>      console.log(e.message);<br>    }<br>  }<br>  }</pre><p>Now Call the startCheckout function and pass the payment_session_id and order_id in the session object and then you will be able to make payments from the SDK.</p><p>After calling the startCheckout function you will be redirected to the following screen</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/460/1*rNQdOMcKyIno6fKPdJ5DrQ.png" /></figure><p>Now choose your preferred payment method and click on pay in test environment you’ll be able to see two simulation options</p><ol><li>To simulate Success</li><li>To Simulate Failure</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/448/1*qO7w-i4oL6BHlQC9IzqIww.png" /></figure><p>After Clicking on Success or Failure the payment will be completed</p><p>4. Now all there is left to verify payment which will be done from backend and it’s done.</p><p>Thus, we have successfully integrated the Cashfree payment service in our React Native app easily.</p><h4>Thank you</h4><p>Hope you liked this article. Happy Learning!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=cba7fa9f2b2" width="1" height="1" alt=""><hr><p><a href="https://medium.com/vectoscalar/cashfree-sdk-integration-in-react-native-app-cba7fa9f2b2">Cashfree SDK integration in React Native App</a> was originally published in <a href="https://medium.com/vectoscalar">VectoScalar</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Authenticating user via Firebase Authorizer using Spring Boot]]></title>
            <link>https://medium.com/vectoscalar/authenticating-user-via-firebase-authorizer-using-spring-boot-ff0a86c659d1?source=rss----ecfc2f0ad21e---4</link>
            <guid isPermaLink="false">https://medium.com/p/ff0a86c659d1</guid>
            <dc:creator><![CDATA[Akhilesh Anthwal]]></dc:creator>
            <pubDate>Wed, 03 Jan 2024 05:37:35 GMT</pubDate>
            <atom:updated>2024-01-03T05:37:35.282Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*tbG2cc3X_8J6NtA8tKwJNw.png" /></figure><p>In this article, we’ll learn how to secure our spring boot API using firebase authorization.</p><h4>Introduction to Firebase Authentication</h4><p>It is essential to authenticate users, and it is much harder if we have to write all this code on our own. This is done very easily with the help of Firebase. <em>Firebase Authentication</em> provides backend services, easy-to-use SDKs, and ready-made UI libraries to authenticate users to your app. It supports authentication using passwords, phone numbers, and popular federated identity providers like Google, Microsoft, Facebook, Twitter, and more.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7V3tnXG7gFPLu0A4DlsEPQ.png" /><figcaption>supports popular federated identity provider</figcaption></figure><h4>How Authentication Works..?</h4><p>We first get authentication credentials from the user to sign a user into our app.</p><ul><li>Credentials can be the user’s email address and password.</li><li>The credential can be an OAuth token from an identity provider.</li></ul><p>We then pass these credentials to the Firebase Authentication SDK. Backend services will then verify those credentials and return a response to the client.</p><figure><img alt="" src="https://cdn-images-1.medium.com/proxy/1*cTuV8eCzZzGzvWhb2Vyatg.png" /><figcaption>authentication</figcaption></figure><p>And after a successful sign in-</p><ul><li>Firebase provides us an authentication token, which is then checked in whatever place we need to authenticate or authorize a user, be it front-end or back-end.</li><li>We can access the user’s basic profile information.</li></ul><h4><strong>Prerequisites</strong></h4><ul><li>Make sure that you have a server app.</li><li>Admin Java SDK — Java 8+</li></ul><p><strong><em>Let’s get started:</em></strong></p><h4><strong>Configure Firebase</strong></h4><p>First, enable the SignIn Methods. I enable Email/Password and Google and create a user. You can simply add a user using email/password.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*89CaB_mKiWZLzgIH81yxCw.png" /></figure><h4>Configuring Firebase in Spring Boot Project</h4><p>To configure the firebase in the spring boot project first download the servicesAccountKey.json file from your Firebase Project setting.</p><p>Go to Project Setting -&gt; Service Account-&gt; Scroll down and click on create and then click on Generate new Private Key.</p><p>This will generate and download Private Key to access the Firebase Admin SDK.</p><blockquote>*make sure to keep this file secure</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xwmclZnntEhJ5KZN9Qr4HA.png" /></figure><p>Download the servicesAccountKey.json file and paste it into the resource folder of your spring boot project. This is the location where we access our private key.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/367/1*vm5x_vqYVeUxobfnWOZKsw.png" /><figcaption>servicesAccountKey.json</figcaption></figure><h4>Add the SDK</h4><p>If you are setting up a new project, you need to install the SDK for the language of your choice. If you use Maven to build your application, you can add the following dependency to your pom.xml:</p><pre>&lt;dependency&gt;<br>  &lt;groupId&gt;com.google.firebase&lt;/groupId&gt;<br>  &lt;artifactId&gt;firebase-admin&lt;/artifactId&gt;<br>  &lt;version&gt;9.0.0&lt;/version&gt;<br>&lt;/dependency&gt;</pre><p>for reference, you can visit <a href="https://firebase.google.com/docs/admin/setup#windows">https://firebase.google.com/docs/admin/setup#windows</a></p><h4>Retrieve ID tokens on clients</h4><p>When a user or device successfully signs in, Firebase creates a corresponding ID token that uniquely identifies them and grants them access to several resources, such as Firebase Realtime Database and Cloud Storage. You can re-use that ID token to identify the user or device on your custom backend server. To retrieve the ID token from the client, make sure the user is signed in and then get the ID token from the signed-in user:</p><pre>firebase.auth().currentUser.getIdToken(/* forceRefresh */ true).then(function(idToken) {<br>   // Send token to your backend via HTTPS<br>   // …<br>}).catch(function(error) {<br>   // Handle error<br>});</pre><p>Once you have an ID token, you can send that JWT to your backend and validate it using the Firebase Admin SDK, or using a third-party JWT library if your server is written in a language that Firebase does not natively support.</p><h4>Initialize Firebase SDK</h4><pre>//firebase service account<br><br>@Configuration<br>public class FirebaseInitialization { <br><br>@Bean <br>public void initialization() { <br>try{ <br> <br>FileInputStream serviceAccount =<br>  new FileInputStream(&quot;./serviceAccountKey.json&quot;); <br> <br>// serviceAccountKey.json file containing the key, store this json file to your resource folder<br><br>FirebaseOptions options = new FirebaseOptions.Builder()<br>  .setCredentials(GoogleCredentials.fromStream(serviceAccount))<br>  .build();<br> <br>FirebaseApp.initializeApp(options);<br> } catch (Exception error) { <br>error.printStackTrace(); <br>}<br>     }<br> }</pre><h4><strong>Verify ID tokens using the Firebase Admin SDK</strong></h4><p>The Firebase Admin SDK has a built-in method for verifying and decoding ID tokens. If the provided ID token has the correct format, is not expired, and is properly signed, the method returns the decoded ID token. You can grab the uid of the user or device from the decoded token.</p><p>Follow the <a href="https://firebase.google.com/docs/admin/setup">Admin SDK setup instructions</a> to initialize the Admin SDK with a service account. Then, use the verifyIdToken() method to verify an ID token:</p><pre>/ idToken comes from the client app<br>FirebaseToken decodedToken = FirebaseAuth.getInstance().verifyIdToken(idToken);<br>String uid = decodedToken.getUid();</pre><h4><strong>HTTP filter to check firebase token</strong></h4><pre>public class FireBaseTokenFilter extends OncePerRequestFilter { <br>/**<br>  * Authenticating user via fireBase authorizer verify fireBase token and extract<br>  * Uid and Email from token<br>  */<br>  @Override<br>  protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {<br><br>    //Extracts token from header<br>    String token = request.getHeader(&quot;Authorization&quot;); <br><br>    //checks if token is there<br>    if (token == null ) <br>      throw new ResponseStatusException(HttpStatus.UNAUTHORIZED,&quot;Missing token!&quot;); <br>  <br>    FirebaseToken decodedToken = null;<br>    try { <br>      //verifies token to firebase server <br>      decodedToken = FirebaseAuth.getInstance().verifyIdToken(token); <br>    } catch (FirebaseAuthException e) {<br>       throw new ResponseStatusException(HttpStatus.UNAUTHORIZED,&quot;Error! &quot;+e.toString()); <br>        }<br>     //if token is invalid <br>     if (decodedToken==null){ <br>        throw new ResponseStatusException(HttpStatus.UNAUTHORIZED,&quot;Invalid token!&quot;); <br>      }<br><br>    //Extract Uid and Email<br>    String uid= decodedToken.getUid();<br>    String email = decodedToken.getEmail();<br><br>    /*<br>    //set Uid and Email to request<br>    void setAttribute(java.lang.String name, java.lang.Object o)<br>    */<br><br>    request.setAttribute(“uid”, uid);<br>    request.setAttribute(“email”,email);<br><br>    chain.doFilter(request,response); <br>    }<br>}</pre><p>This is how we can authenticate any user in our spring boot application using firebase.</p><blockquote>Thanks for reading!</blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ff0a86c659d1" width="1" height="1" alt=""><hr><p><a href="https://medium.com/vectoscalar/authenticating-user-via-firebase-authorizer-using-spring-boot-ff0a86c659d1">Authenticating user via Firebase Authorizer using Spring Boot</a> was originally published in <a href="https://medium.com/vectoscalar">VectoScalar</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Get Started Visualizing MongoDB Data with Charts and Dashboards]]></title>
            <link>https://medium.com/vectoscalar/get-started-visualizing-mongodb-data-with-charts-and-dashboards-4b03fb0514fd?source=rss----ecfc2f0ad21e---4</link>
            <guid isPermaLink="false">https://medium.com/p/4b03fb0514fd</guid>
            <dc:creator><![CDATA[Abhiraj Varshney]]></dc:creator>
            <pubDate>Mon, 18 Dec 2023 05:13:27 GMT</pubDate>
            <atom:updated>2023-12-18T05:13:27.013Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*q3rlMeyX3jUVwH1nRRDOWA.jpeg" /></figure><p>MongoDB is a popular NoSQL database that organizations around the world use to store and manage large amounts of data. While MongoDB provides powerful tools for querying and analyzing data, it can be challenging to gain a comprehensive understanding of your data without visualizing it.</p><p>If you are new to MongoDB data analytics and visualization, you might be wondering how to get started. If this is the case, you’re lucky — there’s an easier way! In this blog post, we’ll cover some of the important key ways by which we can leverage MongoDB’s powerful visualization features to create charts and dashboards that make sense of our data.</p><p>Charts and dashboards are a great way to analyze and visualize the data stored in MongoDB databases. These charts can help you make better decisions, gain new insights, and optimize processes within your company. I’ll show you how to quickly create basic charts using MongoDB with a little setup and some coding knowledge required.</p><p>Let’s get started-</p><p>Suppose you have an e-commerce database, and it is spread over multiple collections containing thousands of documents in it. Now, if you are required to offer a dashboard with a visual representation of your data saved in MongoDB, then one of the solutions that come in our mind is to</p><ol><li>Create and publish a set of back-end APIs that are designed for querying your MongoDB collection.</li><li>Select a library to make charts.</li><li>Use the data you’ve gotten from the back end to operate on an object data model as the charting library specifies.</li><li>Write front-end code to interact with your back-end APIs.</li></ol><p>Now, what if I told you that we could do all the above-specified tasks by just using Charts on MongoDB Cloud, i.e., MongoDB Atlas, in just a few clicks with some additional features like</p><ol><li>Auto refreshing(can also be customized)</li><li>Secured as role-based permissions are required to access</li><li>Layout can be configurable</li></ol><p>You would be like 🥰🤗.</p><p>Let’s now quickly jump to <a href="https://www.mongodb.com/atlas">Atlas</a> and begin our expedition to learn.</p><blockquote><a href="https://www.mongodb.com/atlas">https://www.mongodb.com/atlas</a></blockquote><p>Sign up if you don’t have an account on Atlas or log in. Your console should look like this after creating a cluster. To create a cluster, hop on to the following link-</p><blockquote><a href="https://www.mongodb.com/docs/atlas/create-connect-deployments/">https://www.mongodb.com/docs/atlas/create-connect-deployments/</a></blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*VzB3-bWnaUZlpyQDUK0qXw.png" /><figcaption>MongoDB Atlas Console</figcaption></figure><p>Click on Charts, and you will get land on the dashboard page with an empty dashboard already created with your username.</p><p>In most circumstances, you will already have a set of data. If you don’t have any data, then use the below link to load the sample data to Atlas.</p><blockquote><a href="https://www.mongodb.com/docs/atlas/sample-data/sample-mflix/">https://www.mongodb.com/docs/atlas/sample-data/sample-mflix/</a></blockquote><blockquote><a href="https://github.com/neelabalan/mongodb-sample-dataset/tree/main/sample_mflix">https://github.com/neelabalan/mongodb-sample-dataset/tree/main/sample_mflix</a></blockquote><p>Now, let us create our first chart to display the total no. of movies we have in our collection.</p><p>We will be choosing the movie’s data source from our collections.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*wcNcWtbjhdJj4eLkNNfXqA.gif" /><figcaption>Loading the Data Set</figcaption></figure><p>After selecting the movie’s data source, we will choose the chart type from the charts list.</p><ol><li>Choose a chart type as Number from the drop-down menu.</li><li>Drag the field’_id’ from the fields list on the left to the aggregation column on its right.</li><li>Apply aggregation as a count method.</li><li>Rename the chart as No. of Movies.</li></ol><p><strong><em>Bonus:</em></strong> You can also filter the chart as per the requirements. I applied the filter on the country name to give me the total no. of movies in India.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Q-yGWFKPPvJP7OfIAgQc4A.gif" /><figcaption>Number of Movies with filter</figcaption></figure><p>Similarly, we can make another chart for ratings of the movies. We can choose a donut type for the purpose.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*XrLl-fIUgXDO1UuRsi3KSQ.gif" /><figcaption>Movie Reviews</figcaption></figure><p>Feeling Simple and Easy. I hope you have liked the warm-up. Time to buckle up ⚡⚡⚡.</p><p>Now let’s create another chart with multiple fields. We are creating a bar chart of the Number of Movies in a Year and a line chart to show comparisons between average critic score and viewer review score. So, let us select grouped combo from the chart type.</p><ol><li>Select the year as X-axis from fields on the left-hand side and also bin them to 10 to make it a decade.</li><li>Select ‘_id’ as columns and choose aggregation as count. It will create a bar chart.</li><li>For the line chart, select the ‘meter’ field from ‘tomatoes.viewer’ and apply aggregation to mean as we need an average score in each decade.</li><li>Repeat the above step and select the ‘meter’ field from ‘tomatoes.critic’.</li><li>Now in the filter section, select the ‘year’ with the minimum value inclusive.</li><li>Now plot the line chart onto the secondary axis and call it ‘rating.’</li></ol><p><strong><em>Bonus: </em></strong>We can also customize our charts. We can change the colors of the lines and bar, rewrite the name of the fields, and can also format the number type, and much more.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*zalWHTOJEUX78XDKi6DHnA.gif" /><figcaption>Multiple Charts(<strong>No. of Movies, Average Critic vs Viewer Review Scores)</strong></figcaption></figure><p>Now, let us jump to some coding parts. MongoDB charts allow you to write a query or add a missed or newly calculated field.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*auwKSkUnZsVgevfFIuBjJQ.jpeg" /></figure><p>We will create a new chart, <strong>Most Prolific Actors, </strong>using a stacked bar type of chart. Here, we will be adding a new calculated field with the name ‘tomatometer,’ and the aggregation query to add the field is</p><pre>{<br>  &quot;$cond&quot;: [<br>    {<br>      &quot;$gte&quot;: [<br>        &quot;$tomatoes.critic.meter&quot;,<br>        0<br>      ]<br>    },<br>    {<br>      &quot;$cond&quot;: [<br>        {<br>          &quot;$gte&quot;: [<br>            &quot;$tomatoes.critic.meter&quot;,<br>            60<br>          ]<br>        },<br>        &quot;Fresh&quot;,<br>        &quot;Rotten&quot;<br>      ]<br>    },<br>    &quot;Not Rated&quot;<br>  ]<br>}</pre><p>We will repeat almost all the steps stated above to create the chart. We will also limit the value to 10 results only.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ZyOEV4ygL6zaxx1iuwjMQg.gif" /><figcaption>Stacked Chart (<strong>Most Prolific Actors</strong>)</figcaption></figure><p>We have covered almost most of our bases with the Charts. Now, let’s talk about Dashboard in MongoDB.</p><p>Dashboards are a combination of charts put together to show all of your data in one place. Dashboards are crucial for gaining insight into numerous focus points of your data in a single display because each chart uses data from a single MongoDB collection or view. Users can share dashboards with one another.</p><p>You can customize the layout of the charts, size, and position of the chart in the dashboard only. You can also place filters for the whole dashboards applicable to whole charts if they contain the same source data, or you can choose the chart to get filtered.</p><p>You can also apply role-based permissions for sharing for security reasons. Unauthenticated access can be accessed from anywhere, as authenticated access can only be accessed after verifying permissions.</p><p>Set up Dashboard permissions, following <a href="https://www.mongodb.com/docs/charts/dashboard-permissions/"><em>this</em></a> simple documentation.</p><p>You can lock out the dashboard or share it in the organization itself.</p><p>Now comes the embedding part of the dashboard, which is one of the main features. Embedding a MongoDB dashboard into your web application can be a valuable way to provide users with an intuitive interface for interacting with the database. It can be handy for applications relying heavily on MongoDB to store and retrieve data.</p><p>You can use an iframe element to embed the dashboard into your own application. An iframe is an HTML element that allows you to embed another webpage within the current webpage. Here’s an example of how to use an iframe to embed the MongoDB dashboard:</p><pre>&lt;iframe<br>style=&quot;background: #FFFFFF;<br>border: none;<br>border-radius: 2px;<br>box-shadow: 0 2px 10px 0 rgba(70, 76, 79, .2);&quot;<br>width=&quot;640&quot; height=&quot;480&quot; <br>src=&quot;https://charts.mongodb.com/mongodb-charts-twsqq/embed/dashboards<br>?id=a1b2c3d4-a1b2-c3d4-9766-47b0b2daaff3&amp;theme=light&amp;attribution=false&quot;&gt;<br>&lt;/iframe&gt;</pre><p>It will display the MongoDB dashboard within an iframe element in your application. You can customize the iframe size by adjusting the width and height attributes.</p><p>One thing to remember is that the MongoDB dashboard is designed to be used as a standalone application and may not fit seamlessly into your application’s layout. You may need some styling to make the dashboard look and feel like a natural part of your application.</p><p>Another option is using MongoDB JavaScript SDK to access your application’s dashboard data directly. It requires more setup, but it allows you to thoroughly integrate the dashboard functionality into your application.</p><p>To use the JavaScript SDK, you’ll need to install it by running the following command:</p><pre>import ChartsEmbedSDK from &quot;@mongodb-js/charts-embed-dom&quot;;<br><br>const sdk = new ChartsEmbedSDK({<br>  baseUrl: &#39;https://charts.mongodb.com/charts-charts-fixture-tenant-zdvkh&#39;,<br>});<br><br>// embed a chart<br>const chart = sdk.createChart({<br>  chartId: &#39;48043c78-f1d9-42ab-a2e1-f2d3c088f864&#39;,<br>});<br><br>// render the chart into a container<br>chart<br>  .render(document.getElementById(&#39;chart&#39;))<br>  .catch(() =&gt; window.alert(&#39;Chart failed to initialise&#39;));<br><br>// refresh the chart whenever #refreshButton is clicked<br>document<br>  .getElementById(&#39;refreshButton&#39;)<br>  .addEventListener(&#39;click&#39;, () =&gt; chart.refresh());<br><br>// embed a dashboard<br>const dashboard = sdk.createDashboard({<br>  dashboardId: &#39;61d02578-6148-4c87-9cad-1fbaef50a0d3&#39;,<br>});<br><br>// render the chart into a container<br>dashboard<br>  .render(document.getElementById(&#39;dashboard&#39;))<br>  .catch(() =&gt; window.alert(&#39;Dashboard failed to initialise&#39;));</pre><p>Using the JavaScript SDK allows you to fully customize how dashboard functionality is integrated into your application. However, it requires more code and setup than an iframe and may only be suitable for some use cases.</p><p>Embedding the MongoDB dashboard into your own application is a great way to provide your users with an easy-to-use interface for managing their data. With just a few lines of code, you can bring the power of the MongoDB dashboard into your application.</p><p>Finally, charts and dashboards are essential to any analytics strategy, especially when using a document-based database. With MongoDB, there are many ways of visualizing data in charts and graphs. This collection of examples will help you leverage these features to create your own charts and dashboards with MongoDB.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-BbtIB6tmSKPLwW5rr3Dpw.jpeg" /></figure><p>Do explore more &amp; expand with your significant use cases.</p><p>I hope you enjoyed reading &amp; learned something new.</p><p>Don’t feel shy to appreciate with some claps.👏👏👏</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4b03fb0514fd" width="1" height="1" alt=""><hr><p><a href="https://medium.com/vectoscalar/get-started-visualizing-mongodb-data-with-charts-and-dashboards-4b03fb0514fd">Get Started Visualizing MongoDB Data with Charts and Dashboards</a> was originally published in <a href="https://medium.com/vectoscalar">VectoScalar</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Migration of Android App API Level to 31 (Android 12) in React-Native]]></title>
            <link>https://medium.com/vectoscalar/migration-of-android-app-api-level-to-31-android-12-in-react-native-c0bfe9696ca3?source=rss----ecfc2f0ad21e---4</link>
            <guid isPermaLink="false">https://medium.com/p/c0bfe9696ca3</guid>
            <dc:creator><![CDATA[Sanjeev Kumar]]></dc:creator>
            <pubDate>Wed, 13 Dec 2023 08:19:40 GMT</pubDate>
            <atom:updated>2023-12-13T08:19:40.678Z</atom:updated>
            <content:encoded><![CDATA[<p>I have recently upgraded my android application to API level to 31 (Android 12). I had deal with some issue while migrating the android app to API level to 31 (Android 12).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vg0fyj9CrrtCwspydDciYA.jpeg" /><figcaption>Android 12</figcaption></figure><p>Currently my project pointing to 30 (Android 11).</p><p><strong>&gt; How to migrate android app to API level 31 (Android 12):-</strong></p><p><strong>Step 1) Update <em>targetSdkVersion</em> and <em>compileSdkVersion</em></strong></p><p>In order to update the target level upgrade <em>targetSdkVersion</em> and <em>compileSdkVersion</em> in <strong><em>app/build.gradle</em></strong></p><pre>android {<br>    compileSdkVersion 31<br><br>    defaultConfig {<br>        minSdkVersion 23<br>        targetSdkVersion 31<br>        applicationId &quot;com.example.applicationname&quot;<br>        versionCode 1<br>        versionName &quot;1.0&quot;<br>        resConfigs &quot;en&quot;<br>        multiDexEnabled true<br>    }</pre><p><strong>Step2) Add </strong><strong><em>android:exported</em> in </strong><strong><em>android/app/src/main/AndroidManifest.xml</em></strong></p><p>Add android:exported=&quot;true/false&quot; attribute in &lt;activity&gt;...&lt;/activity&gt;, &lt;service&gt;…&lt;/service&gt;, &lt;receiver&gt;…&lt;/receiver&gt; and &lt;provider&gt;…&lt;/provider&gt; like:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*H3gHlTfW7iJoJy2TbhULLQ.png" /><figcaption>Example of android:exported = “true/false”</figcaption></figure><p><strong>When to use </strong><strong><em>true</em> and </strong><strong><em>false</em> :-</strong></p><p>Whether the broadcast receiver can receive messages from non-system sources outside its application — “<em>true</em>&quot; if it can, and &quot;<em>false</em>&quot; if not. If &quot;false&quot;, the only messages the broadcast receiver can receive are those sent by the system, components of the same application, or applications with the same user ID.</p><p>If unspecified, the default value depends on whether the broadcast receiver contains intent filters. If the receiver contains at least one intent filter, then the default value is “true&quot;. Otherwise, the default value is &quot;false&quot;.</p><p>In Short:-</p><blockquote><strong>We need to set exported as </strong>true<em> if any components need to be accessible from outside of our app (either by OS or other apps).</em></blockquote><pre><strong>NOTE: If we don&#39;t add android:exported=&quot;true/false&quot;. App will not run</strong></pre><p><strong>Step 3) Update</strong><strong><em>&lt;uses-permissions /&gt;</em> and Libraries:-</strong></p><p>You must have to update some user permission in <em>android/app/src/main/AndroidManifest.xml</em>. Consider <a href="https://developer.android.com/google/play/requirements/target-sdk#pre12">official documentation</a> for permission upgradation.</p><p><strong>Step 4) Sync and run the application:-</strong></p><p>Sync your application in android studio and try to run the application. It will run successfully.</p><p>If you face problem to run the application due to some other libraries then try upgrade the library to latest version which supports the API level 31 (Android 12).</p><ul><li><strong>&gt; Still having problem in running the application:-</strong></li></ul><ol><li>Open <em>android/app/src/main/AndroidManifest.xml</em> file in Android Studio.</li><li>Open <em>Merged Manifest</em> which will show the error in errors section if there is any.</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/726/1*P0BS4EbDWdLon0TsmAgYVQ.png" /><figcaption>Merged Manifest</figcaption></figure><p>3. Find the errors in <em>Merged Manifest</em> and make the changes</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*wmPvsp5-arqnLoFqEG8KiQ.png" /><figcaption>Merged Manifest Error Example</figcaption></figure><p>4. Open AndroidManifest.xml from <em>Merged Manifest</em> of different libraries which are giving the <em>android:exported</em> error and add the <em>android:exported=&quot;true/false&quot;</em> attribute.</p><p>5. Patch the library using below commands:</p><pre><strong>Supposing you have mylib.aar in your current directory, try the following:</strong><br><br>$ unzip myLib.aar -d tempFolder # or other extracting tool<br># Change whatever you need<br>$ jar cvf myNewLib.aar -C tempFolder/ .</pre><p>6. Sync and run the application.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c0bfe9696ca3" width="1" height="1" alt=""><hr><p><a href="https://medium.com/vectoscalar/migration-of-android-app-api-level-to-31-android-12-in-react-native-c0bfe9696ca3">Migration of Android App API Level to 31 (Android 12) in React-Native</a> was originally published in <a href="https://medium.com/vectoscalar">VectoScalar</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Block screenshot in React Native for specific screen (Android)]]></title>
            <link>https://medium.com/vectoscalar/block-screenshot-in-react-native-for-specific-screen-android-66e49f931c70?source=rss----ecfc2f0ad21e---4</link>
            <guid isPermaLink="false">https://medium.com/p/66e49f931c70</guid>
            <dc:creator><![CDATA[Lakshya Munjal]]></dc:creator>
            <pubDate>Thu, 07 Dec 2023 06:20:45 GMT</pubDate>
            <atom:updated>2023-12-07T06:20:45.381Z</atom:updated>
            <content:encoded><![CDATA[<p>Hey folks!<br>Today we will understand how we can disable screenshot and screen recording on specific screens in React Native (Android). There can be screens in your app which have sensitive data and we need to not allow the user to take the screenshot.<br>We need to write Native Modules to achieve this.</p><p>Let’s do some coding now!</p><ol><li>Move to <em>android/app/src/main/java/com/your-app-name/</em></li><li>Create a file <em>PreventScreenshotModule.java</em> or any name you want.</li></ol><pre>package com.your-app-name;<br><br>import com.facebook.react.bridge.ReactApplicationContext;<br>import com.facebook.react.bridge.ReactContextBaseJavaModule;<br>import com.facebook.react.bridge.ReactMethod;<br>import com.facebook.react.bridge.Promise;<br><br>import android.view.WindowManager;<br><br>import static com.facebook.react.bridge.UiThreadUtil.runOnUiThread;<br><br>public class PreventScreenshotModule extends ReactContextBaseJavaModule {<br>    private static final String PREVENT_SCREENSHOT_ERROR_CODE = &quot;PREVENT_SCREENSHOT_ERROR_CODE&quot;;<br>    private final ReactApplicationContext reactContext;<br><br>    PreventScreenshotModule(ReactApplicationContext context) {<br>        super(context);<br>        reactContext = context;<br>    }<br><br>    @Override<br>    public String getName() {<br>        return &quot;PreventScreenshotModule&quot;;<br>    }<br><br>    @ReactMethod<br>    public void forbid(Promise promise) {<br>        runOnUiThread(new Runnable() {<br>            @Override<br>            public void run() {<br>                try {<br>                    getCurrentActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);<br>                    promise.resolve(&quot;Screenshot taking locked.&quot;);<br>                } catch(Exception e) {<br>                    promise.reject(PREVENT_SCREENSHOT_ERROR_CODE, &quot;Forbid screenshot taking failure.&quot;);<br>                }<br>            }<br>        });<br>    }<br><br>    @ReactMethod<br>    public void allow(Promise promise) {<br>        runOnUiThread(new Runnable() {<br>            @Override<br>            public void run() {<br>                try {<br>                    getCurrentActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE);<br>                    promise.resolve(&quot;Screenshot taking unlocked.&quot;);<br>                } catch (Exception e) {<br>                    promise.reject(PREVENT_SCREENSHOT_ERROR_CODE, &quot;Allow screenshot taking failure.&quot;);<br>                }<br>            }<br>        });<br>    }<br>}</pre><p>3. Now it’s time to create <em>PreventScreenshotPackage.java </em>in the same directory as above <em>android/app/src/main/java/com/your-app-name/</em></p><pre>package com.your-app-name;<br><br>import com.facebook.react.ReactPackage;<br>import com.facebook.react.bridge.NativeModule;<br>import com.facebook.react.bridge.ReactApplicationContext;<br>import com.facebook.react.uimanager.ViewManager;<br><br>import java.util.Arrays;<br>import java.util.Collections;<br>import java.util.List;<br><br>public class PreventScreenshotPackage implements ReactPackage {<br><br>    @Override<br>    public List&lt;ViewManager&gt; createViewManagers(ReactApplicationContext reactContext) {<br>        return Collections.emptyList();<br>    }<br><br>    @Override<br>    public List&lt;NativeModule&gt; createNativeModules(ReactApplicationContext reactContext) {<br>        return Arrays.&lt;NativeModule&gt;asList(new PreventScreenshotModule(reactContext));<br>    }<br>}</pre><p>4. Add this package to your <em>MainApplication.java</em></p><pre>@Override<br>protected List&lt;ReactPackage&gt; getPackages() {<br>    @SuppressWarnings(&quot;UnnecessaryLocalVariable&quot;)<br>    List&lt;ReactPackage&gt; packages = new PackageList(this).getPackages();<br>    packages.add(new PreventScreenshotPackage());<br><br>    return packages;<br>}</pre><p>Now it’s time to access the methods defined in <em>PreventScreenshotModule.java </em>in your component/screen.</p><p>For accessing this, we’ll create a custom hook.</p><p>5. Navigate to src/hooks/ and create a hook with whatever name you like. I’m creating <em>useCustomScreenshot.js</em></p><pre>import { useEffect } from &#39;react&#39;;<br>import { NativeModules } from &quot;react-native&quot;;<br>import { useNavigation } from &quot;@react-navigation/native&quot;;<br><br>const useCustomScreenshot = () =&gt; {<br>  const navigation = useNavigation();<br><br>  const forbidScreenshot = async () =&gt; {<br>    try {<br>      const result = await NativeModules.PreventScreenshotModule.forbid();<br>      console.log(result);<br>    } catch (e) {<br>      console.log(e);<br>    }<br>  };<br><br>  const allowScreenshot = async () =&gt; {<br>    try {<br>      const result = await NativeModules.PreventScreenshotModule.allow();<br>      console.log(result);<br>    } catch (e) {<br>      console.log(e);<br>    }<br>  };<br><br>  useEffect(() =&gt; {<br>    navigation.addListener(&#39;blur&#39;, () =&gt; {<br>      // when user moves to some other screen &#39;blur&#39; event will be triggered, <br>      // again enable screenshot<br>      allowScreenshot();<br>    });<br>  }, []);<br><br>  return { allowScreenshot, forbidScreenshot };<br>};<br><br>export default useCustomScreenshot;</pre><p>6. Now move to the screen where you need to disable the screen and use this piece of code there.</p><pre>import React from &quot;react&quot;;<br>import { View } from &quot;react-native&quot;;<br>import { useFocusEffect } from &quot;@react-navigation/native&quot;;<br><br>const HomeScreen = () =&gt; {<br>  const { forbidScreenshot } = useCustomScreenshot();<br><br>  useFocusEffect(<br>    useCallback(() =&gt; {<br>      forbidScreenshot();<br>    }, [])<br>  );<br><br>  return (<br>    &lt;View style={styles.container}&gt;<br>      &lt;Text&gt;Home&lt;/Text&gt;<br>    &lt;/View&gt;<br>  );<br>};</pre><p>Done! This is all you need to make things work.</p><p><strong>Note: This will also record a black screen while screen recording and show a black screen when screen is shared on a call.</strong></p><p>Happy Coding!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=66e49f931c70" width="1" height="1" alt=""><hr><p><a href="https://medium.com/vectoscalar/block-screenshot-in-react-native-for-specific-screen-android-66e49f931c70">Block screenshot in React Native for specific screen (Android)</a> was originally published in <a href="https://medium.com/vectoscalar">VectoScalar</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>