<?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[Stories by Rosário Pereira Fernandes on Medium]]></title>
        <description><![CDATA[Stories by Rosário Pereira Fernandes on Medium]]></description>
        <link>https://medium.com/@thatfire.dev?source=rss-60764aad5eb3------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*EKXMQoQq_52f8k3wR7jbEw.jpeg</url>
            <title>Stories by Rosário Pereira Fernandes on Medium</title>
            <link>https://medium.com/@thatfire.dev?source=rss-60764aad5eb3------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Mon, 22 Jun 2026 08:03:03 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@thatfire.dev/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Using Firebase In-App-Messaging on an Android app]]></title>
            <link>https://proandroiddev.com/using-firebase-in-app-messaging-on-an-android-app-f2802757f00b?source=rss-60764aad5eb3------2</link>
            <guid isPermaLink="false">https://medium.com/p/f2802757f00b</guid>
            <category><![CDATA[android-app-development]]></category>
            <category><![CDATA[kotlin]]></category>
            <category><![CDATA[in-app-messaging]]></category>
            <category><![CDATA[firebase]]></category>
            <dc:creator><![CDATA[Rosário Pereira Fernandes]]></dc:creator>
            <pubDate>Fri, 10 Jul 2020 21:59:19 GMT</pubDate>
            <atom:updated>2022-06-10T13:37:11.672Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9xRKS2ZMW9FgjoTrF0evKg.jpeg" /><figcaption>Photo by <a href="https://unsplash.com/@thoughtcatalog?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Thought Catalog</a> on <a href="https://unsplash.com/s/photos/writing?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><h4>The many ways to trigger and customize messages</h4><p>Released almost 2 years ago, In-App-Messaging is a Firebase product that developers can use to send targeted messages (in form of dialogs) to their users. Setting it up and sending a test message is pretty straight forward, but there’s more that can be done to improve the User Experience.<br>In this blog post, I’ll show some of the different ways to trigger and customize in-app messages.</p><h3>Getting Started 👶</h3><p>As mentioned above, sending a test message from <strong>Firebase In-App-Messaging </strong>(abbreviated as <strong>FIAM</strong> from this point on) is pretty simple and can be done in 4 steps:</p><ol><li>Add the FIAM and Analytics dependencies to your build.gradle(app):</li></ol><pre>implementation <strong>&quot;com.google.firebase:firebase-inappmessaging-ktx:$fiamVersion&quot;</strong><br>implementation <strong>&quot;com.google.firebase:firebase-analytics-ktx:$analyticsVersion&quot;</strong></pre><p>2. Run the app to find your Installation ID in the logcat:</p><pre>I/FIAM.Headless: Starting InAppMessaging runtime with Installation ID <strong>YOUR_INSTALLATION_ID</strong></pre><p>3. Go to the In-App Messaging tab on the Firebase Console, click on “New Campaign” and enter a <strong>Title</strong> for that campaign.</p><p>4. Click “Test on your Device”, enter your <strong>Installation ID </strong>and click on “Test” to send the message.</p><p>Once you relaunch the app, you should now see your test message being displayed :)</p><p>Now if you wish to send the message to the users of your app, you can go ahead and finish composing that campaign, as explained in the <a href="https://firebase.google.com/docs/in-app-messaging/compose-campaign">Firebase Documentation</a>.</p><h3>Seasonal Campaigns 🐰🎄</h3><p>This is my favorite FIAM feature and perhaps the most used one. It allows you to schedule messages to be shown during a specified time range. So you can use it to inform your users about Easter discounts, Christmas sales or even that great deal that your company is offering during a pandemic. You can also specify how often the message is shown to the user.</p><p>The good part is that you don’t need to write any code to achieve that. You can do it all straight from the Firebase Console. When composing your campaign, you’ll come across <strong>Step 3</strong> — Scheduling your message. That’s where you can set a <strong>start date</strong> and an <strong>end date</strong>.</p><p>You’ll notice that the messages are triggered by <a href="https://firebase.google.com/docs/analytics/events?platform=android"><strong>Analytics events</strong></a><strong> </strong>(which is why we added analytics to the app). Two events that are logged automatically by Firebase Analytics are on_foreground and app_launch, so these will always be available for you to choose from when composing a campaign. If you’ve previously logged events to Firebase Analytics, those events will also be available to choose from. Otherwise, you can also create a new event right there.</p><h3>Trigger messages with Analytics events 💬</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/297/1*fv-UPN866tK90LudI2MzuA.png" /></figure><p>Let’s say we have an e-commerce app and we want to show users a dialog when they’re about to perform a checkout. When composing the campaign on the Firebase Console, we’ll set it to only be triggered on the begin_checkout event:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/247/1*Plo9KRsHls6LrAWn4s7ZiA.png" /></figure><p>We could log the begin_checkout event to Firebase Analytics when the user clicks on the checkout button:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/dab92e3a5ee82b0f5e8cc77487d41e09/href">https://medium.com/media/dab92e3a5ee82b0f5e8cc77487d41e09/href</a></iframe><p>And our message should be displayed to the user. :)</p><p>Alternatively, you can trigger the event without actually logging the data to Firebase Analytics, by calling:</p><pre>Firebase.inAppMessaging.triggerEvent(&quot;begin_checkout&quot;)</pre><h3>Customize the message behavior 🔧</h3><p>Now if the user clicks on the “Get Code” button from our in-app-message, we might want to take an action, such as notifying our backend about the fact that we should now give that user a discount.</p><p>We can do that by adding the promo code as custom metadata on Step 5 when we’re composing the campaign on the Console:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/365/1*5APPRmT3Gjlrl5JhB3QZ1Q.png" /></figure><p>And then we can obtain that promo code on the app by adding a click listener to our FIAM instance:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f194a709675e28888a59a64f4db8210d/href">https://medium.com/media/f194a709675e28888a59a64f4db8210d/href</a></iframe><h3>Customize the way it looks 🎨</h3><p>Maybe you have created a unique and kick-ass custom design for your app dialogs and would like to apply it to your In-App-Message.</p><p>You can do so by calling setMessageDisplayComponent() on the <strong>onResume()</strong> lifecycle event of your Activity and checking what type of message the app received and then get the metadata (title, caption, actions, etc) included so that you can use it on your custom dialog.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f91c7be98ed1978b064d471b0c70088d/href">https://medium.com/media/f91c7be98ed1978b064d471b0c70088d/href</a></iframe><p>And that’s all for now. If you would like to learn more about Firebase In-App-Messaging, you can check the <a href="https://firebase.google.com/docs/in-app-messaging">Documentation</a>.</p><p>Thanks for reading. If you have thoughts on FIAM or Firebase in general, leave a comment bellow or reach out to <a href="https://twitter.com/_rpfernandes">me on Twitter </a>and I’ll be happy to have a chat about it. :)</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f2802757f00b" width="1" height="1" alt=""><hr><p><a href="https://proandroiddev.com/using-firebase-in-app-messaging-on-an-android-app-f2802757f00b">Using Firebase In-App-Messaging on an Android app</a> was originally published in <a href="https://proandroiddev.com">ProAndroidDev</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Loading Images From Cloud Storage on Android using Coil]]></title>
            <link>https://medium.com/better-programming/loading-images-from-cloud-storage-on-a-kotlin-android-app-d1574a059e04?source=rss-60764aad5eb3------2</link>
            <guid isPermaLink="false">https://medium.com/p/d1574a059e04</guid>
            <category><![CDATA[mobile]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[kotlin]]></category>
            <category><![CDATA[android-app-development]]></category>
            <dc:creator><![CDATA[Rosário Pereira Fernandes]]></dc:creator>
            <pubDate>Mon, 15 Jun 2020 14:24:30 GMT</pubDate>
            <atom:updated>2020-06-19T11:54:42.762Z</atom:updated>
            <content:encoded><![CDATA[<h3>Loading Images From Cloud Storage on Android using Coil</h3><h4>Coroutines and extension functions for the rescue</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*k3_xSqvv0mj16W9oB9KfZw.jpeg" /><figcaption>Photo by <a href="https://unsplash.com/@invictar1997?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Soragrit Wongsa</a> on <a href="https://unsplash.com/s/photos/polaroid?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><p>If you’re developing an Android app and you’re storing images in cloud storage for Firebase to later display in your app, you’re probably using an image loading library such as <a href="https://github.com/bumptech/glide">Glide</a>, <a href="https://github.com/square/picasso">Picasso</a>, <a href="https://github.com/facebook/fresco">Fresco</a>, or <a href="https://github.com/firebase/FirebaseUI-Android/blob/master/storage/README.md">firebase-ui-storage</a>. Yes, these libraries can do the job, but what if I told you there’s a more pleasant and efficient way?</p><p>In this article, I’ll introduce you to the new kid in town, <a href="https://coil-kt.github.io/coil/"><strong>Coil</strong></a><strong>,</strong> and I’ll show you how to use it to load your cloud storage images with less boilerplate code.<br>I’ll assume you’re already familiar with cloud storage for Firebase and already know how to use it in an Android app. If not, you may want to take a look at the <a href="https://firebase.google.com/docs/storage">Documentation</a>.</p><h3>Coil (Coroutines Image Loader)</h3><p>Coil is an open-source Image Loading Library for Android. Unlike the other pre-existing libraries (Glide, Picasso, etc), Coil was built entirely in Kotlin and is backed by Coroutines. It’s also:</p><ul><li><strong>Easy to use:</strong> Because it leverages some Kotlin language features, such as Kotlin Extension Functions, which allows you to keep your code simple and concise.</li><li><strong>Lightweight: </strong>It adds ~2000 methods to your APK, which is almost the same as Picasso and a little less than Glide.</li><li><strong>Fast:</strong> Its speed compares fairly to Picasso and Glide, as shown in <a href="https://proandroiddev.com/coil-vs-picasso-vs-glide-get-ready-go-774add8cfd40">this benchmark</a>.</li></ul><h3>Getting Started</h3><p>Because Coil uses Java 8, one of the prerequisites is that you enable Java 8 in your Android project. You can do so in your module’s build.gradle file:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a75a9fc0653d5d7f20200bd37003ab1a/href">https://medium.com/media/a75a9fc0653d5d7f20200bd37003ab1a/href</a></iframe><p>Then you add it as a dependency on that same file:</p><pre>dependencies {<br>    // ... other dependencies<br>    <strong>implementation &#39;io.coil-kt:coil:0.11.0&#39;</strong><br>}</pre><h4>Usage</h4><p>The simplest way to use Coil is by calling the ImageView.load() extension functions that the library provides:</p><pre>// URL<br>imageView.<strong>load(</strong>&quot;https://www.example.com/image.jpg&quot;<strong>)</strong><br><br>// Resource<br>imageView.<strong>load(</strong>R.drawable.image<strong>)</strong></pre><p>You can also specify a placeholder or any other additional configuration on a trailing lambda:</p><pre>imageView.<strong>load(</strong>&quot;https://www.example.com/image.jpg&quot;<strong>)</strong> <strong>{</strong><br>    <strong>placeholder(</strong>R.drawable.image<strong>)</strong><br>    <strong>transformations(</strong>CircleCropTransformation()<strong>)</strong><br><strong>}</strong></pre><p>Apart from the extension functions, Coil also provides other ways to load images, such as <a href="https://coil-kt.github.io/coil/requests/">Requests</a> and <a href="https://coil-kt.github.io/coil/image_loaders/">Image Loaders</a>, which I won’t go through for brevity. But you can learn more about them in their <a href="https://coil-kt.github.io/coil/getting_started/">Documentation</a>.</p><h3>Coil Plus Cloud Storage for Firebase</h3><p>Let’s say you have an image stored on Cloud Storage for Firebase, which can be accessed using the path “users/me/profile.png”. To display this image on an ImageView in your Android App, you may need to get its download URL first and then pass it to Coil, as <a href="https://firebase.google.com/docs/storage/android/download-files#download_data_via_url">the docs</a> suggest:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ba3e7f5beaa0922512c1f39298eb1f68/href">https://medium.com/media/ba3e7f5beaa0922512c1f39298eb1f68/href</a></iframe><p>It looks simple, right? But what if I told you that even this can be simplified? <br>That’s where <a href="https://firebaseopensource.com/projects/rosariopfernandes/firecoil/">firecoil</a> comes in.</p><h3>firecoil: Firebase and Coil</h3><p><a href="https://firebaseopensource.com/projects/rosariopfernandes/firecoil/">firecoil</a> is an open-source library that allows you to load images with Coil by simply providing the StorageReference of said image. To use firecoil, you’ll need to add the jitpack maven to your project’s build.gradle file:</p><pre>repositories {<br>    // ...<br>    <strong>maven { url &#39;https://jitpack.io&#39; }</strong><br>}</pre><p>Next add the firecoil dependency to your module’s build.gradle file:</p><pre><strong>implementation &#39;com.github.rosariopfernandes:firecoil:0.2.0&#39;</strong></pre><p>Now with firecoil you no longer need to get the download URL. You can simply pass your StorageReference to the ImageView.load() extension function provided by the library:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5a8644ace4278edcd73784e52affd14f/href">https://medium.com/media/5a8644ace4278edcd73784e52affd14f/href</a></iframe><p>Since firecoil is built on top of Coil, you can also use a trailing lambda to specify additional configuration:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e1af39e589f2c9dfd04fa1c50923a8c5/href">https://medium.com/media/e1af39e589f2c9dfd04fa1c50923a8c5/href</a></iframe><p>That’s it! With this simple and concise snippet, your app should now have beautiful images displayed.</p><h3>Resources</h3><ul><li>Coil on GitHub: <a href="https://github.com/coil-kt/coil">https://github.com/coil-kt/coil</a></li><li>firecoil on GitHub: <a href="https://github.com/rosariopfernandes/firecoil">https://github.com/rosariopfernandes/firecoil</a></li><li>Coil Documentation: <a href="https://coil-kt.github.io/coil/">https://coil-kt.github.io/coil/</a></li><li>firecoil Documentation: <a href="https://firebaseopensource.com/projects/rosariopfernandes/firecoil">https://firebaseopensource.com/projects/rosariopfernandes/firecoil</a></li><li>Glide vs. Picasso vs. Coil Benchmark: <a href="https://proandroiddev.com/coil-vs-picasso-vs-glide-get-ready-go-774add8cfd40?gi=f21b6d717eec">https://proandroiddev.com/coil-vs-picasso-vs-glide-get-ready-go-774add8cfd40</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d1574a059e04" width="1" height="1" alt=""><hr><p><a href="https://medium.com/better-programming/loading-images-from-cloud-storage-on-a-kotlin-android-app-d1574a059e04">Loading Images From Cloud Storage on Android using Coil</a> was originally published in <a href="https://betterprogramming.pub">Better Programming</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Firebase News: April 26th — May 09th?]]></title>
            <link>https://medium.com/@thatfire.dev/firebase-news-april-26th-may-09th-4075ee879346?source=rss-60764aad5eb3------2</link>
            <guid isPermaLink="false">https://medium.com/p/4075ee879346</guid>
            <category><![CDATA[android-app-development]]></category>
            <category><![CDATA[firebase]]></category>
            <category><![CDATA[ios-app-development]]></category>
            <category><![CDATA[firebase-extensions]]></category>
            <category><![CDATA[cloud-functions]]></category>
            <dc:creator><![CDATA[Rosário Pereira Fernandes]]></dc:creator>
            <pubDate>Mon, 11 May 2020 10:01:01 GMT</pubDate>
            <atom:updated>2020-05-13T12:44:49.002Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*RYgcmVpE133EiA9EO8aVaw.png" /></figure><h3>Firebase News: April 26th — May 09th</h3><p>This is Article 02 of “Firebase News” — a series of articles where you can find the most recent news from the Firebase World. A new article is posted every 1–2weeks discussing (most of) the changes made on the official tools, SDKs, sample apps and some of the 3rd party libraries. Also expect to see what’s new on: the <a href="https://firebase.googleblog.com/">official Firebase blog</a>, the <a href="https://medium.com/firebase-developers">Firebase Developers Medium publication</a>, the <a href="https://www.youtube.com/user/Firebase/">Firebase Youtube Channel</a> and the <a href="https://firebaseopensource.com/">Firebase Open Source site</a>.</p><p><strong>Disclaimer: I do not work for Firebase, Google or any other organization here mentioned. Views, thoughts, and opinions expressed in this article belong solely to me, and not necessarily to these organizations.</strong></p><h3>Firebase Admin SDKs</h3><h4>Python Admin SDK</h4><p><a href="https://firebase.google.com/support/release-notes/admin/python#version_420_-_30_april_2020">Version 4.2.0</a> was released and it introduces a newtenant_mgt module that provides APIs to work with <a href="https://cloud.google.com/blog/products/identity-security/multi-tenancy-support-identity-platform-now-generally-available">Multi-tenancy</a>. You can read more about Multi-tenant applications in <a href="https://medium.com/firebase-developers/multi-tenant-applications-with-firebase-and-google-cloud-4d0d02b7d859">this blog post</a> by <a href="https://medium.com/u/7f5798693e07">Hiranya Jayathilaka</a>.</p><h4>Node.js Admin SDK</h4><p>Starting in <a href="https://firebase.google.com/support/release-notes/admin/node#version_8120_-_06_may_2020">version 8.12.0</a>, developers using the NodeJS Admin SDK can now retrieve and delete users in bulk, using the newly added getUsers() and deleteUsers() functions. Learn more about it on <a href="https://medium.com/@hiranya911/firebase-fetching-and-deleting-user-accounts-in-bulk-44ad84926539">this other blog post</a> by Hiranya.</p><h4>.Net Admin SDK</h4><p><a href="https://firebase.google.com/support/release-notes/admin/dotnet#version_1120_-_06_may_2020">Version 1.12.0</a> of the .Net Admin SDK has 2 new methods to manage Firebase session cookies: CreateSessionCookieAsync() and VerifySessionCookieAsync().</p><h3>Firebase Open Source</h3><p>Two (2) new Kotlin projects have been added to <a href="https://firebaseopensource.com">firebaseopensource.com</a> :</p><ul><li><a href="https://firebaseopensource.com/projects/GitLiveApp/firebase-kotlin-sdk/">firebase-kotlin-sdk</a> from <a href="https://github.com/GitLiveApp/">GitLiveApp</a>. As the name suggests, this project is an unofficial Kotlin SDK for Firebase. Unlike the official Firebase KTX, this project does not extend the Java SDK, instead, it was built on top of it, with Kotlin-first design in mind. It also supports writing for Kotlin multiplatform, which means you can use the same code for Android, iOS and JavaScript.</li><li><a href="https://firebaseopensource.com/projects/raipankaj/kotfirebase/">kotfirebase</a> by <a href="https://github.com/raipankaj">raipankaj</a> - a Kotlin wrapper for the Firebase SDK. The project aims to bring the usage of each API down to one line of code.</li></ul><h3>Firebase Youtube Channel</h3><p>We have four (4) new videos on the Youtube Channel:</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2F5GzFDXvZxKM%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D5GzFDXvZxKM&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2F5GzFDXvZxKM%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/087ddd8cc30923997a2302a39952bca7/href">https://medium.com/media/087ddd8cc30923997a2302a39952bca7/href</a></iframe><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FJAaCUmQ6LBo%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DJAaCUmQ6LBo&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FJAaCUmQ6LBo%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/114d74aa9ab0f8d224869b6a1b4fd8a6/href">https://medium.com/media/114d74aa9ab0f8d224869b6a1b4fd8a6/href</a></iframe><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FyE3AiheI54g%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DyE3AiheI54g&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FyE3AiheI54g%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/933b1b09cb8e875bd837392fce9cbf94/href">https://medium.com/media/933b1b09cb8e875bd837392fce9cbf94/href</a></iframe><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2Ff6u3AnOKZd0%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3Df6u3AnOKZd0&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2Ff6u3AnOKZd0%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/302a77eeaab121dcf65e97c0e0ce8da6/href">https://medium.com/media/302a77eeaab121dcf65e97c0e0ce8da6/href</a></iframe><h3>Other Minor Releases</h3><h4>Android</h4><ul><li><a href="https://firebase.google.com/support/release-notes/android#installations_v16-3-0">Firebase Installations 16.3.0</a> and <a href="https://firebase.google.com/support/release-notes/android#iid_v20-1-7">Firebase Instance ID 20.1.7</a> improved the detection of invalid FirebaseOptions values.</li><li><a href="https://firebase.google.com/support/release-notes/android#crashlytics_gradle_plugin_v2-1-0">Crashlytics Gradle plugin version 2.1.0</a> - minor bug fixes.</li><li><a href="https://firebase.google.com/support/release-notes/android#appdistro_gradle_plugin_v1-4-1">App Distribution Gradle plugin version 1.4.1</a> - bug fixes.</li><li><a href="https://firebase.google.com/support/release-notes/android#analytics_v17-4-1">Analytics 17.4.1</a> - the Event <a href="https://firebase.google.com/docs/reference/android/com/google/firebase/analytics/FirebaseAnalytics.Event#SELECT_CONTENT">SELECT_CONTENT</a> has been un-deprecated.</li></ul><h4>iOS</h4><p><a href="https://firebase.google.com/support/release-notes/ios#version_6240_-_may_5_2020">Version 6.24.0</a> - bug fixes to Analytics, Authentication, Crashlytics, Realtime Database, Cloud Firestore, In App Messaging, FCM and Remote Config.</p><h4>Firebase Tools 8.2.0</h4><p><a href="https://github.com/firebase/firebase-tools/releases/tag/v8.2.0">Version 8.2.0</a> - Minor improvements and dependency updates.</p><h4><strong>Firebase Extensions</strong></h4><ul><li><a href="https://github.com/firebase/extensions/releases/tag/storage-resize-images-0.1.7">storage-resize-images 0.1.7</a> - fixed a bug that prevents resized images from being shown in the Firebase Console.<br>Fixed an issue where the extensions would resize the wrong image, due to caching errors.</li><li><a href="https://github.com/firebase/extensions/releases/tag/firestore-translate-text-0.1.2">firestore-translate-text 0.1.2</a> - target languages can now be reconfigured.</li><li><a href="https://github.com/firebase/extensions/releases/tag/firestore-send-email-0.1.4">firestore-send-email 0.1.4</a> - the “default FROM” parameter now accepts a name before the email. E.g: Friendly User &lt;foobar@example.com&gt;</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4075ee879346" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Firebase Auth + One Tap UI on Android]]></title>
            <link>https://medium.com/firebase-developers/firebase-auth-one-tap-86ca80a80973?source=rss-60764aad5eb3------2</link>
            <guid isPermaLink="false">https://medium.com/p/86ca80a80973</guid>
            <category><![CDATA[firebase]]></category>
            <category><![CDATA[google-sign-in]]></category>
            <category><![CDATA[google-developers-group]]></category>
            <category><![CDATA[firebaseauthentication]]></category>
            <category><![CDATA[android-app-development]]></category>
            <dc:creator><![CDATA[Rosário Pereira Fernandes]]></dc:creator>
            <pubDate>Wed, 29 Apr 2020 23:56:23 GMT</pubDate>
            <atom:updated>2025-11-25T02:23:00.958Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*EFU8DF1LUfr1jLhoU_178A.png" /></figure><h4>Learn how to implement One Tap sign-in and sign-up on your existing Firebase Android app</h4><p>Google has recently introduced <a href="https://developers.google.com/identity/one-tap/android/overview">One Tap sign-in and sign-up on Android</a>. This service allows your app’s new users to create an account, securely with just a single tap on a beautiful dialog.<br>Users who already have an account can also have the same experience, so they don’t need to remember the username or password they had previously used when they created an account in that app.<br>You can read more about One Tap in <a href="https://medium.com/androiddevelopers/one-tap-sign-in-for-android-apps-2259ce15bc2c">this other post</a>.</p><p>Here’s what that beautiful dialog looks like:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/378/1*ExyWmpskey_jr471HiLKAw.png" /></figure><p>In this post, I’ll show you how to connect the One Tap UI with Firebase Authentication.</p><h3>Firebase Auth with Google Sign-In</h3><p>I’ll assume that you’ve already implemented Google Sign-in using Firebase Auth on your Android app, so I’ll not go over the steps on how to do that. But if you haven’t, you can still do so by following <a href="https://firebase.google.com/docs/auth/android/google-signin#kotlin">this guide on the documentation</a>. Also, I’ll be using some of the methods created on this same documentation, so in case you see a method/property that you don’t recognize, please be sure to look for it on that page or on the <a href="https://github.com/rosariopfernandes/FirebaseAuthOneTapUI">sample app</a> I’ve created.</p><p>Google’s One Tap UI comes bundled in com.google.android.gms:play-services-auth , which you might already be using, since this library is needed when you’re implementing Google Sign-In. Just check the dependencies on your build.gradle(app) file to make sure you’re using version 18.0.0 or higher.</p><p>Now the next thing we need to do is declare some variables and initialize them on the Activity’s onCreate() or (in my case) the fragment’s onViewCreated():</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/effcc0809db53ec11ddda4d97a38a09b/href">https://medium.com/media/effcc0809db53ec11ddda4d97a38a09b/href</a></iframe><p>Notice that on our BeginSignInRequest we’re setting filterByAuthorizedAccounts to <strong>true</strong>. This means the OneTap UI will only display accounts that have previously logged in to this app. If you’re displaying the Google Sign -In option on a <strong>Sign up </strong>screen, you should set filterByAuthorizedAccounts to <strong>false</strong> instead, so that the UI displays all user accounts available on that Android device.</p><p>Those variables that we just declared will be used to initiate the One Tap sign-in flow on our updateUI() method (the one called from onStart()):</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/740c63de630c13c3a7fd167e275c54d7/href">https://medium.com/media/740c63de630c13c3a7fd167e275c54d7/href</a></iframe><p>If the OnFailureListener gets executed, it means the user has never logged in to this app before or another error occurred. One other error that might happen is the 24-hour cooldown period, which the OneTap UI uses as a way to limit the prompts that it shows. If you face this error during development, the <a href="https://developers.google.com/identity/one-tap/android/get-saved-credentials#disable-one-tap">documentation</a> recommends:</p><blockquote>“… reset the cooldown by clearing Google Play services’ app storage.”</blockquote><p>But otherwise, if the SuccessListener gets executed instead, startIntentSenderForResult() will display the One Tap UI for users to select the account they wish to use in order to continue. So we need to update our onActivityResult code in order to receive and handle the result coming from One Tap:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/7b1809517f053b3c076a776a89535ac9/href">https://medium.com/media/7b1809517f053b3c076a776a89535ac9/href</a></iframe><p>Note that if the user closes the One Tap UI, getSignInCredentialFromIntent() returns an ApiException with the status code CommonStatusCodes.<em>CANCELED</em>. In that case, we set our variable back to false and we don’t prompt the user again. Although using this variable may work fine, you can also use <a href="https://developer.android.com/training/data-storage/shared-preferences">SharedPreferences</a> instead, if you prefer.</p><p>And that’s it! You can now run your app and test the One Tap UI. This is what the One Tap UI with Google Sign-In should look like:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/360/1*FuwCdQ0PckQcE_Bg4KfkoQ.png" /></figure><h3>Firebase Auth with Email/Password</h3><p>If your app also provides Email/Password authentication, One Tap UI can also help your users signing in to your app using that method. You’ll need to update the BeginSignInRequest we created earlier and handle the result in the onActivityResult() function:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/fc459a055079b756f3e3835c8d93cb78/href">https://medium.com/media/fc459a055079b756f3e3835c8d93cb78/href</a></iframe><p>This password request feature is backed by the <a href="https://developer.android.com/guide/topics/text/autofill">Autofill</a> framework which was introduced in Android 8.0 (API level 26), so you’ll need to <a href="https://developer.android.com/guide/topics/text/autofill-optimize#kotlin">optimize your app for Autofill</a>. This means you should add android:autofillHints to your EditText’s XML as shown below:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f03352336d52820503e1100bc755d3ed/href">https://medium.com/media/f03352336d52820503e1100bc755d3ed/href</a></iframe><p>And this should do it. Now in order to test this feature, you’ll need to enable Autofill on your testing device, if you’re not already using it. To do that, make sure your device is running Android 8.0 (or above) and navigate to <strong>Settings &gt; System &gt; Language and Input &gt; Autofill</strong> and select an Autofill framework.</p><p>Once you login for the first time on the app, Autofill will prompt if you want to save your credentials. If you accept, the next time you login to the app, One Tap UI should display your saved credentials:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/360/1*g98h9zqiHJRtRS94YA9ShA.png" /></figure><p>Additionally, if you also have a website or a web app on the same Firebase project, you can also <a href="https://developers.google.com/identity/smartlock-passwords/android/associate-apps-and-sites">enable automatic sign-in between apps and websites</a>, which will allow your users to sign-in to your web app with the password they saved on the mobile app and vice-versa.</p><p>And that’s all for today. I hope this helps you implement One Tap sign-in and sign-up in your Firebase Apps. You can find the sample app on Github:</p><p><a href="https://github.com/rosariopfernandes/FirebaseAuthOneTapUI">rosariopfernandes/FirebaseAuthOneTapUI</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=86ca80a80973" width="1" height="1" alt=""><hr><p><a href="https://medium.com/firebase-developers/firebase-auth-one-tap-86ca80a80973">Firebase Auth + One Tap UI on Android</a> was originally published in <a href="https://medium.com/firebase-developers">Firebase Developers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Firebase News: April 19th — 25th]]></title>
            <link>https://medium.com/@thatfire.dev/firebase-news-01-188d00d2c1a6?source=rss-60764aad5eb3------2</link>
            <guid isPermaLink="false">https://medium.com/p/188d00d2c1a6</guid>
            <category><![CDATA[firebase]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[ios-app-development]]></category>
            <category><![CDATA[android-app-development]]></category>
            <dc:creator><![CDATA[Rosário Pereira Fernandes]]></dc:creator>
            <pubDate>Mon, 27 Apr 2020 11:27:15 GMT</pubDate>
            <atom:updated>2020-04-27T11:27:15.655Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*RYgcmVpE133EiA9EO8aVaw.png" /></figure><h3>Firebase News: April 19th — 25th</h3><h4>The Hello World</h4><p>This is Article 01 of “Firebase News” - a series of articles where you can find the most recent news from the Firebase World. A new article will be posted every 1–2weeks discussing (most of) the changes made on the official tools, SDKs, sample apps and some of the 3rd party libraries. Also expect to see what’s new on: the <a href="https://firebase.googleblog.com/">official Firebase blog</a>, the <a href="https://medium.com/firebase-developers">Firebase Developers Medium publication</a>, the <a href="https://www.youtube.com/user/Firebase/">Firebase Youtube Channel</a> and the <a href="https://firebaseopensource.com/">Firebase Open Source site</a>.</p><p><strong>Disclaimer: I do not work for Firebase, Google or any other organization here mentioned. Views, thoughts, and opinions expressed in this article belong solely to me, and not necessarily to these organizations.</strong></p><h3>Firebase Android SDK</h3><p>Let’s start with the Android SDK, one of my personal favorites.</p><p>A bunch of libraries from the Android SDK were updated. Most notably:</p><h4>Authentication got a KTX library</h4><p>General Availability of the <a href="http://firebase.googleblog.com/2020/03/firebase-kotlin-ga.html">KTX libraries was announced</a> by the end of March 2020 and recently, Authentication got its KTX library.</p><p>This means that if you use Kotlin to build your Android Apps, you can update your code to be more concise and idiomatic while leveraging some of the Kotlin language features.<br>To get started with Authentication KTX, simply add the -ktx suffix to the gradle dependency and make sure you’re using version 19.3.1 or above:</p><pre>dependencies {<br>  // Other dependencies</pre><pre>  implementation &quot;com.google.firebase:firebase-auth-ktx:19.3.1&quot;<br>}</pre><p>This allows you to use some of the new Extension Functions:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d25923c59c014e9e7b68fbdaa324fa63/href">https://medium.com/media/d25923c59c014e9e7b68fbdaa324fa63/href</a></iframe><p>You can find more Extensions included in the Auth KTX on the <a href="https://firebase.google.com/docs/reference/kotlin/com/google/firebase/auth/ktx/package-summary">reference docs</a>.</p><h4>Firebase Crashlytics SDK out of beta</h4><p>This year, Firebase announced a <a href="https://firebase.google.com/docs/crashlytics/get-started-new-sdk?platform=android">new Crashlytics SDK</a>, which should replace <a href="https://firebase.google.com/docs/crashlytics/get-started">Fabric’s Crashlytics</a>. The new SDK, that just graduated from beta, is more consistent with the other Firebase SDKs and offers improved APIs. It also includes a <a href="https://github.com/firebase/firebase-android-sdk/tree/master/firebase-crashlytics-ndk">SDK for NDK</a> and a gradle Plugin. This gradle plugin should replace the previous fabric plugin that was necessary to use the Crashlytics SDK.</p><p>What I personally like about this SDK is the fact that it offers a Singleton just like all the other Firebase libraries. This makes it easier to mock a Crashlytics instance when writing tests for you app. So instead of Fabric.with(getContext(), Crashlytics()), you’ll now be using FirebaseCrashlytics.getInstance().</p><p>And to learn how to upgrade to the new Firebase Crashlytics SDK, you can check the <a href="https://firebase.google.com/docs/crashlytics/upgrade-sdk?platform=android">migration guide</a>.</p><h4>Atomic field value increments for the Realtime Time Database</h4><p>This is a feature that I was hoping for. As you might know, it is hard to keep counters or any other field that might suffer concurrent modifications. In order to solve this problem, you can either <a href="https://github.com/firebase/functions-samples/tree/master/child-count">make use of Cloud Functions</a> or <a href="https://firebase.google.com/docs/database/android/read-and-write#save_data_as_transactions">update your fields using Transactions</a>. Starting in version 19.3.0, you can now use ServerValue.increment(double) to increment your counters atomically.</p><p>For example, if you were to increment a user’s score in the database, you can simply do:</p><pre>val reference: DatabaseReference = ...<br>reference.child(&quot;userId&quot;).updateChildren(<br>  hashMapOf(&quot;score&quot; to ServerValue.increment(5)) //incrementing by 5<br>)</pre><h3>Firebase iOS SDK</h3><p>Obviously, the iOS SDK couldn’t be left behind. Like the Android SDK, it also got:</p><ul><li>The <a href="https://firebase.google.com/docs/crashlytics/upgrade-sdk">new Crashlytics SDK</a> out of beta;</li><li>Realtime Database’s <a href="https://firebase.google.com/support/release-notes/ios#realtime-database">atomic field value increments</a> with ServerValue.increment().</li></ul><h3>Server Admin SDKs</h3><h4>Node.js</h4><ul><li>Since this SDK depends on the JavaScript client SDK, it has inherited the admin.database.ServerValue.increment() for atomic field value increments.</li><li>ML Kit for Firebase now provides an API for creating, updating, getting, listing, publishing, unpublishing, and deleting Firebase-hosted custom ML models. You can use this API by calling admin.machineLearning() learn more on the <a href="https://firebase.google.com/docs/ml-kit/manage-hosted-models#nodejs">Firebase Documentation</a>.</li><li>Another API that was recently added is the Remote Config API, which enables developers to programmatically manage the set of JSON-formatted parameters and conditions known as the Remote Config template. The API can be used by admin.remoteConfig() and you can see all the available functions on the <a href="https://firebase.google.com/docs/reference/admin/node/admin.remoteConfig.RemoteConfig">Reference Docs</a>.</li></ul><h4>Python</h4><p>Just like the Node.js Admin SDK, the Python Admin SDK also got the api to manage hosted ML modules. You can use it by importing the ml module: from firebase_admin import ml. More usage details on the <a href="https://firebase.google.com/docs/ml-kit/manage-hosted-models#python">Firebase Documentation</a>.</p><h4>.NET</h4><p>The Admin .NET Authentication SDK has 2 new APIs: RevokeRefreshTokensAsync()for revoking any previously issued refresh tokens to a user and VerifyIdTokenAsync() to check if a given ID token has been revoked since it was issued.</p><h3>Firebase Extensions</h3><h4>storage-resize-images now supports WebP</h4><p>The storage-resize-images extension was backed by the <a href="https://www.npmjs.com/package/imagemagick">imagemagick</a> npm module, which does not include WebP support. In order to provide WebP support, the Extensions Team changed the extension to use the <a href="https://www.npmjs.com/package/sharp">sharp</a> npm module instead. This change comes in <a href="https://github.com/firebase/extensions/releases/tag/storage-resize-images-v0.1.6">version 0.1.6</a> of the extension. See the documentation to find out <a href="https://firebase.google.com/docs/extensions/manage-installed-extensions?platform=console#update-version">how to upgrade extensions</a>.</p><h3>Firebase Youtube Channel</h3><p>A <a href="https://www.youtube.com/watch?v=6iTmteRd07Q">new video</a> from the <a href="https://www.youtube.com/playlist?list=PLl-K7zZEsYLkTjfUJvjiPZ14F5c81uDuN">Build a to-do list app w/ SwiftUI &amp; Firebase Semi-live Series</a> was posted. On this one, <a href="https://medium.com/u/ea0b1eb1f5d2">Peter Friese</a> shows how to implement Sign in with Apple on iOS using Firebase Authentication for users to sign in with Apple ID.</p><h3>[Bonus] Firebase Virtual Meetups</h3><p>This month, Firebase has also been hosting a series of <a href="https://events.withgoogle.com/firebase-virtual-meetup/">Virtual Meetups</a> aimed at bringing together Firebasers and developers in intimate online settings.<br>Last week they hosted “Building Secure Apps with Firebase” with a great presentation from <a href="https://medium.com/u/d46602c082f7">Megha Bangalore</a> and this week, on April 29th, they’ll be hosting “Achieving Continuous Deployment with Firebase Remote Config” with <a href="https://medium.com/u/731f9e4a45a3">Steve Wilber</a>. You can see the schedule for future meetups and/or register to attend on <a href="https://events.withgoogle.com/firebase-virtual-meetup/registrations/new/">their website</a>.</p><p>And that’s it for this week. Bellow you can find the other minor releases that happened over the past week.</p><p>As mentioned in the beginning of the article, this is the first one of the series. So please let me know in the comments if this was helpful to you and what would you like to see featured here.</p><p>Hat tip to <a href="https://medium.com/u/cb2c4874d3e9">Chet Haase</a> for the amazing job he’s been doing with the <a href="https://medium.com/androiddevelopers/now-in-android-16-9a282ebd3f42">Now In Android</a> Blog, Video and Podcast series, which was the inspiration for the creation of this series.</p><h3>Other Minor Releases</h3><h4>Android</h4><ul><li><a href="https://firebase.google.com/support/release-notes/android#analytics_v17-4-0">Analytics 17.4.0</a> - bug fixes and deprecation of the <a href="https://android-developers.googleblog.com/2019/11/still-using-installbroadcast-switch-to.html">Install Referrer Broadcast</a> Receiver;</li><li><a href="https://firebase.google.com/support/release-notes/android#firestore_v21-4-3">Cloud Firestore 21.4.3</a> - limited the number of concurrent document lookups it will perform when resolving inconsistencies in the local cache.</li><li><a href="https://firebase.google.com/support/release-notes/android#messaging_v20-1-6">Cloud Messaging 20.1.6</a> - Bug fixes</li><li><a href="https://firebase.google.com/support/release-notes/android#inappmessaging_v19-0-6">In-App-Messaging</a> and In-App-Messaging Display 19.0.6 - bug fixes.</li><li><a href="https://firebase.google.com/support/release-notes/android#iid_v20-1-6">Firebase Instance IID 20.1.6</a> - improved FirebaseOptions validation. This may not sound like a huge change, but it might show you some errors if you do not provide an api key, an app id and a project id. In some cases, re-downloading the google-services.json file from the Firebase Console might help you fix the errors.</li><li><a href="https://firebase.google.com/support/release-notes/android#mlkit-common_v22-1-1">MLKit Common 22.1.1</a>, <a href="https://firebase.google.com/support/release-notes/android#performance_v19-0-7">Predictions 19.0.7</a> and <a href="https://firebase.google.com/support/release-notes/android#remote-config_v19-1-4">Remote Config 19.1.4</a> - internal changes to later migrate from Firebase Instance IID to <a href="https://firebase.google.com/docs/projects/manage-installations">Firebase Installations</a>.</li></ul><h4>iOS</h4><p>Bug fixes and internal changes on the modules: <a href="https://firebase.google.com/support/release-notes/ios#analytics">Analytics</a>, <a href="https://firebase.google.com/support/release-notes/ios#authentication">Auth</a>, <a href="https://firebase.google.com/support/release-notes/ios#cloud-firestore">Cloud Firestore</a>, <a href="https://firebase.google.com/support/release-notes/ios#firebase-in-app-messaging">In App Messaging</a>, <a href="https://firebase.google.com/support/release-notes/ios#fcm">FCM</a> and <a href="https://firebase.google.com/support/release-notes/ios#storage">Storage</a>.</p><h4>JavaScript (Web) 7.14.2</h4><ul><li><a href="https://firebase.google.com/support/release-notes/js#cloud-firestore">Cloud Firestore</a> now rejects write operations if they cannot be persisted in IndexedDB. Previously, these errors crashed the client. This should also fix more crashes related to IndexedDB.</li><li><a href="https://firebase.google.com/support/release-notes/js#fcm">Cloud Messaging</a> - changed to compare hostname instead of the entire URL to decide if there is a matching window client.</li></ul><h4>Unity 6.14.0</h4><ul><li><a href="https://firebase.google.com/support/release-notes/unity#cloud-firestore">Cloud Firestore</a> - Firestore.LoggingEnabled is replaced with Firestore.LogLevel for consistency with other Firebase Unity APIs and its getter was removed.</li><li><a href="https://firebase.google.com/support/release-notes/unity#crashlytics">Crashlytics</a> - (iOS) Removed references to UIWebView APIs to prevent App Store rejections.</li></ul><h4>Server Admin SDKs</h4><ul><li><a href="https://firebase.google.com/support/release-notes/admin/node#authentication">Node. Auth</a> - Exposed email, email_verified, phone_number, and picture fields from the DecodedIdToken type.</li><li><a href="https://firebase.google.com/support/release-notes/admin/go#version_3121_-_23_april_2020">Go 3.12.1</a> - Deferred credential loading until required, which allows some APIs like auth.VerifyIDToken() to be called without credentials.<br>- Cloud Firestore updated the remote endpoint used by topic management operations.</li></ul><h4>Firebase Extensions</h4><ul><li><a href="https://github.com/firebase/extensions/releases/tag/firestore-bigquery-export-v0.1.4">firestore-bigquer-export-v0.1.4</a> - bug fixes</li></ul><h4>Cloud Functions</h4><ul><li><a href="https://github.com/firebase/firebase-functions/releases/tag/v3.6.1">Cloud Functions v3.6.1</a> - updates TypeScript dependency to fix build issues.</li></ul><h4>Firebase CLI</h4><ul><li><a href="https://github.com/firebase/firebase-tools/releases/tag/v8.1.1">Firebase Tools v8.1.1</a> - Fixes error when deploying Cloud Functions for Firebase from a project subdirectory.</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=188d00d2c1a6" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Kotlin Extension Functions e Coroutines no Firebase]]></title>
            <link>https://medium.com/@thatfire.dev/kotlin-extension-functions-e-coroutines-no-firebase-f8f08d71cdc5?source=rss-60764aad5eb3------2</link>
            <guid isPermaLink="false">https://medium.com/p/f8f08d71cdc5</guid>
            <category><![CDATA[firebase]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[kotlin]]></category>
            <category><![CDATA[medium-em-português]]></category>
            <category><![CDATA[medium-moçambique]]></category>
            <dc:creator><![CDATA[Rosário Pereira Fernandes]]></dc:creator>
            <pubDate>Tue, 09 Apr 2019 09:34:58 GMT</pubDate>
            <atom:updated>2019-04-09T09:34:58.150Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*cdOhrvFRFVN8IPN9DdLcrA.png" /></figure><h4>Desenvolvimento Android mais simples e conciso</h4><blockquote>“Quanto mais simples e conciso for o código, mais rápido você entenderá o que está acontecendo.” — <a href="https://medium.com/u/bda34d240011">Paulo Enoque</a></blockquote><p>É por causa da simplicidade e concisão do <a href="https://medium.com/kotlin-para-android/introdu%C3%A7%C3%A3o-a-kotlin-51a4355f3bc8">Kotlin</a> que muitos desenvolvedores têm optado por esta linguagem de programação para realizarem o seu trabalho.</p><p>Devo recordar também que em Maio de 2017 a Google anunciou que Kotlin passava a ser uma linguagem oficial para desenvolvimento de aplicações Android. De lá para cá, a adoção desta linguagem e, consequentemente, o número de desenvolvedores Kotlin também aumentaram.</p><p>Só um ano e meio depois do Kotlin ser adoptado como linguagem oficial para o Android é que o Firebase incluiu esta linguagem na sua <a href="https://firebase.google.com/docs">documentação oficial</a> :</p><h3>Doug Stevenson 🔥 on Twitter</h3><p>@Firebase code samples for Android are starting to get @kotlin samples to go with Java! Thanks to @daggerdwivedi and @_rpfernandes for the assists here. It&#39;s a tremendous effort overall, and it&#39;s great to have help from the community. https://t.co/PMlAViMf9F #AndroidDev</p><p>Depois de adicionar suporte para o Kotlin na Documentação Oficial, a equipa do Firebase decidiu adicionar também algumas Extension Functions no SDK Android do Firebase (pela mesma razão que eu criei o fireXtensions).</p><p>Leia este artigo completo em <a href="https://developingwith.firebaseapp.com/Kotlin-Features-Firebase/">developingwith.firebaseapp.com</a> .</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f8f08d71cdc5" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Explorando o ML Kit for Firebase]]></title>
            <link>https://medium.com/android-dev-moz/mlkit-537775bd7052?source=rss-60764aad5eb3------2</link>
            <guid isPermaLink="false">https://medium.com/p/537775bd7052</guid>
            <category><![CDATA[firebase]]></category>
            <category><![CDATA[ml-kit]]></category>
            <category><![CDATA[linguagem-natural]]></category>
            <category><![CDATA[android-app-development]]></category>
            <category><![CDATA[medium-moçambique]]></category>
            <dc:creator><![CDATA[Rosário Pereira Fernandes]]></dc:creator>
            <pubDate>Fri, 01 Feb 2019 17:01:00 GMT</pubDate>
            <atom:updated>2019-02-01T17:01:00.886Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*N-7n22WhRw9ydZrMCCnS6Q.png" /></figure><h4>Parte 2 — Linguagem Natural e Identificação de Linguagem</h4><p>Este artigo faz parte da série Explorando o ML Kit for Firebase:</p><ol><li><a href="https://medium.com/android-dev-moz/mlkit-540f8e5438c1">O novo serviço de Machine Learning do Firebase</a></li><li>Linguagem Natural e Identificação de Linguagem</li></ol><p>No ano passado, a equipa do Firebase anunciou um novo SDK que foi adicionado à plataforma — o <a href="https://firebase.google.com/docs/ml-kit/">ML Kit</a>. O ML Kit é um SDK que permite que desenvolvedores utilizem Machine Learning em aplicativos Android e iOS. Se você ainda não conhece o ML Kit, leia o <a href="https://medium.com/android-dev-moz/mlkit-540f8e5438c1">primeiro artigo</a> desta série.</p><p>Quando foi anunciado, o ML Kit só tinha funcionalidades relacionadas com o ramo <a href="https://pt.wikipedia.org/wiki/Vis%C3%A3o_computacional">Visão Computacional</a> (Computer Vision). Mas hoje foi adicionada a primeira funcionalidade do ramo <a href="https://pt.wikipedia.org/wiki/Processamento_de_linguagem_natural">Processamento de Linguagem Natural</a> (Natural Language Processing) — a chamada identificação de linguagem (Language Identification).</p><p>Assim, o ML Kit conta agora com 2 pacotes: o <strong>ML Vision</strong> (sobre o qual falei no <a href="https://medium.com/android-dev-moz/mlkit-540f8e5438c1">artigo anterior</a>) e o <strong>Natural Language</strong> (o tema deste artigo).</p><h3>Natural Language</h3><p>Enquanto que o ML Vision aplica conceitos de Machine Learning em imagens, o pacote Natural Language usa ML no processamento de texto.<br>Atualmente a única funcionalidade inclusa neste pacote é a <a href="https://firebase.google.com/docs/ml-kit/identify-languages"><strong>Identificação de Linguagem</strong></a>, só está disponível para Android ou iOS e só é possível utilizá-la <strong>on-device</strong>, pois ainda não tem uma versão <strong>cloud</strong>.</p><p>Para ter o Natural Language na sua app, você só tem de:</p><ol><li><a href="https://medium.com/android-dev-moz/mlkit-540f8e5438c1">Adicionar o Firebase ao projecto</a>;</li><li>Adicionar a dependência do Natural Language no ficheiro build.gradle:</li></ol><pre><strong>implementation &#39;com.google.firebase:firebase-ml-natural-language:18.1.1&#39;</strong></pre><h4>Identificação de linguagem</h4><p>Como o nome sugere, esta funcionalidade analisa um texto e identifica em que linguagem/idioma esse texto está escrito.</p><p>Para utilizar esta funcionalidade, você tem de adicionar a sua dependência no build.gradle:</p><pre><strong>implementation &#39;com.google.firebase:firebase-ml-natural-language-language-id-model:18.0.2&#39;</strong></pre><p>E na sua Activity/Fragment crie um objecto do tipo FirebaseLanguageIdentification :</p><pre><strong>val </strong>identification<strong> = FirebaseNaturalLanguage.getInstance().languageIdentification</strong></pre><p>Esta funcionalidade pode ser usada de 2 maneiras:</p><ol><li><strong>Identificar a linguagem mais provável<br></strong>É como clicar no botão “Estou com sorte” (I’m feeling lucky) do Google Search. Será mostrada a linguagem com maior probabilidade.<br>Basta utilizar o método:</li></ol><pre><strong>private fun</strong> identificarLinguagemMaisProvavel(texto: <strong>String</strong>) {</pre><pre>identification.identifyLanguage(texto)<br>        .addOnSuccessListener <strong>{ </strong>linguagem <strong>-&gt;<br>            if</strong> (linguagem == &quot;und&quot;) {<br>                // Linguagem desconhecida<br>            } <strong>else</strong> {<br>                // Mostrar a linguagem na UI<br>            }<br>        <strong>}<br>        </strong>.addOnFailureListener <strong>{ </strong>e <strong>-&gt;<br>            </strong>// Ocorreu um erro<br>        <strong>}<br></strong>}</pre><p>Por padrão, o SDK irá mostrar a linguagem mais provável que tenha confidência maior do que 0,5 . Mas se você quiser especificar o número mínimo de confidência, você pode criar um objecto FirebaseLanguageIdentificationOptions e passar para o identificador:</p><pre><strong>val</strong> options = FirebaseLanguageIdentificationOptions.Builder()<br>    .setConfidenceThreshold(0.5f)<br>    .build()<br><br><strong>val</strong> identification = FirebaseNaturalLanguage.getInstance()<br>    .getLanguageIdentification(options)</pre><p>2.<strong> Identificar todas linguagens possíveis:<br></strong>Para ver todas as possibilidades, é só utilizar o método:</p><pre><strong>private fun</strong> identificarLinguagensPossiveis(texto: <strong>String</strong>) {<em><br>    </em>identification.identifyPossibleLanguages(texto)<br>        .addOnSuccessListener <strong>{ </strong>linguagens<strong> -&gt;<br>            var</strong> output = &quot;&quot;<br>            <strong>for (</strong>linguagem <strong>in</strong> linguagens<strong>) {</strong><br>                output += linguagem.<em>languageCode </em>+ &quot; (${linguagem.<em>confidence</em>})\n&quot;<br>            <strong>}</strong><br>            // Mostrar o output na UI<br>        <strong>}<br>        </strong>.addOnFailureListener <strong>{ </strong>e <strong>-&gt;<br>            </strong>// Ocorreu um erro<br>        <strong>}<br></strong>}</pre><p>Por padrão, serão mostradas todas linguagens com confidência maior do que 0,01. Mas se você quiser especificar o número mínimo de confidência, crie um objeto FirebaseLanguageIdentificationOptions como mostrado no método 1 (linguagem mais provável).</p><p>Note que a String retornada pelo SDK é o <a href="https://en.wikipedia.org/wiki/IETF_language_tag">código BCP-47 da linguagem</a>. Você pode encontrar a lista de todas as linguagens suportadas <a href="https://firebase.google.com/docs/ml-kit/langid-support">aqui</a>.</p><p>Veja o código completo da Activity aqui:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/601fb98551811b5aab3f83f251539e0e/href">https://medium.com/media/601fb98551811b5aab3f83f251539e0e/href</a></iframe><p>Identificar linguagens no Android com o Firebase é tão simples quanto isso. Esta funcionalidade pode não parecer útil, mas é sim em alguns casos de uso. Por exemplo: se você tiver criado uma aplicação que é uma espécie de um blog, você pode usar a identificação de linguagens para analisar os blog posts que cada utilizador lê. Se você souber que um certo utilizador lê muitos posts em chinês, talvez seja uma boa ideia recomendar-lhe mais posts em chinês.</p><p>Pude notar que diferentemente do pacote ML Vision, o SDK do Natural Language não ocupa tanto espaço assim. Quando testei o ML Vision pela primeira vez, o APK gerado tinha aproximadamente 15Mb. Enquanto usando o Natural Language, o APK tem aproximadamente 5Mb. Acho que é uma diferença compreensível, pois o SDK do ML Vision certamente usa modelos mais complexos e provavelmente leva consigo algumas imagens usadas para o treinamento destes modelos.</p><p>Vale lembrar que esta é só a primeira funcionalidade que o Firebase traz para o pacote Natural Language. É provável que ao longo do tempo sejam adicionadas mais funcionalidades para este pacote, afinal de contas vem aí o <a href="https://cloud.withgoogle.com/next18/">Cloud Next 19</a> e o <a href="https://events.google.com/io/">Google I/O 2019</a> — dois eventos anuais onde a Google tradicionalmente anuncia novas funcionalidades do Firebase. Irei atualizar este artigo sempre que houverem novidades neste pacote, então continue me seguindo para não perdê-las.</p><p>Caso tenha alguma dúvida ou sugestão, deixe abaixo nos comentários. Se você estiver tentando usar o ML Kit e teve um problema, <a href="https://pt.stackoverflow.com/questions/ask?tags=firebase">coloque ele no StackOverflow</a>, explicando o que você fez e qual foi o erro que teve. De certeza que você obterá ajuda de mim ou de alguém da comunidade. 🙂</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=537775bd7052" width="1" height="1" alt=""><hr><p><a href="https://medium.com/android-dev-moz/mlkit-537775bd7052">Explorando o ML Kit for Firebase</a> was originally published in <a href="https://medium.com/android-dev-moz">GDG Maputo</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Firebase Cloud Functions — Pesquisa de Texto na Base de dados]]></title>
            <link>https://medium.com/android-dev-moz/fcf-search-7fd744b60dee?source=rss-60764aad5eb3------2</link>
            <guid isPermaLink="false">https://medium.com/p/7fd744b60dee</guid>
            <category><![CDATA[firebase]]></category>
            <category><![CDATA[medium-em-português]]></category>
            <category><![CDATA[medium-brasil]]></category>
            <category><![CDATA[firebase-cloud-functions]]></category>
            <category><![CDATA[medium-moçambique]]></category>
            <dc:creator><![CDATA[Rosário Pereira Fernandes]]></dc:creator>
            <pubDate>Thu, 31 Jan 2019 17:01:01 GMT</pubDate>
            <atom:updated>2019-01-31T17:01:01.005Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*e1Uw0fZ3IXoL3zGd7wVn-Q.png" /></figure><h3>Firebase Cloud Functions — Pesquisa de Texto na Base de dados</h3><h4>Algolia &amp; ElasticSearch vs Tocha</h4><p><strong>Este artigo é parte da série Firebase Cloud Functions:</strong></p><ol><li><a href="https://medium.com/@rosariopfernandes/firebase-cloud-functions-f6ed3787fa8d">O que é Firebase Cloud Functions?</a></li><li><a href="https://medium.com/@rosariopfernandes/fcf-comecar-32c984dbc12">Firebase Cloud Functions — Como começar?</a></li><li><a href="https://medium.com/@rosariopfernandes/fcf-fcm-d5828e7eab94">Firebase Cloud Functions + Cloud Messaging</a></li><li><a href="https://medium.com/@rosariopfernandes/fcf-mantain-c95c520089d9">Firebase Cloud Functions — Limpeza e Manutenção da Realtime Database</a></li><li><a href="https://medium.com/@rosariopfernandes/48d503a6cd24">Firebase Cloud Functions — Chame uma função na sua app</a></li><li>Firebase Cloud Functions — Pesquisa de Texto na Base de Dados</li></ol><p>Uma das funcionalidades mais requisitadas à equipe do Firebase é a possibilidade de fazer a clássica “Pesquisa de Texto” na Realtime Database ou no Cloud Firestore. Para quem vem do SQL, esta é a famosa operação LIKE, que é bastante utilizada em caixas/campos de procura de texto.</p><p>Na altura em que a Realtime Database era o único serviço de Base de Dados do Firebase, esta funcionalidade já era pedida por desenvolvedores e, como solução, o Firebase trouxe a <a href="https://github.com/FirebaseExtended/flashlight"><strong>Flashlight</strong></a> — uma biblioteca que conecta-se à plataforma ElasticSearch para permitir estas pesquisas.</p><p>Para quem não conhece, <a href="https://www.elastic.co/products/elasticsearch">ElasticSearch</a> é uma plataforma que faz a indexação de dados para futuras pesquisas. Ela funciona da seguinte forma: Você envia para a plataforma os dados que precisam ser indexados (neste caso, o nó da Realtime Database em que pretende pesquisar) e para fazer a pesquisa você envia uma requisição HTTP para a REST API deles e a API retorna os resultados da sua pesquisa.</p><p>Quando surgiu o Cloud Firestore, vimos várias funcionalidades de consulta(querying) de dados sendo adicionadas, que podemos dizer que são melhorias quando comparadas com as funcionalidades de consulta que existiam na Realtime Database. Mas infelizmente, ainda nada sobre a Pesquisa de Texto. Como solução, o Firebase criou um <a href="https://firebase.google.com/docs/firestore/solutions/search?hl=pt-pt">Tutorial de como conectar Firestore à Algolia para Pesquisa de Texto</a>. <a href="https://www.algolia.com/">Algolia</a> é outra plataforma de indexação muito similar ao ElasticSearch, inclusive funcionam da mesma maneira.</p><p>Apesar destas plataformas parecerem ser a solução perfeita, existem alguns aspetos a ter em conta:</p><ol><li>Você está partilhando os seus dados com plataformas de terceiros;</li><li>É recomendado fazer as requisições em um servidor, pois estas plataformas dão-lhe uma Chave (API KEY) que não deverá ser exposta em aplicações cliente.</li></ol><p>Segundo o <a href="https://firebase.google.com/docs/firestore/solutions/search?hl=pt-pt">tutorial do Firebase</a>, o 2º ponto que mencionei não será um problema, afinal de contas, existe o Firebase Cloud Functions que permite executar algumas funções no lado do servidor (server-side).</p><p>Apesar da combinação “Cloud Functions +Algolia/ElasticSearch” ser perfeita, ela tem um inconveniente: quando estiver a utilizar o plano grátis (Spark Plan) do Firebase, as Cloud Functions não podem enviar requisições para endereços externos (que não fazem parte da Google). Só quem estiver a utilizar um dos planos pagos (Flame ou Blaze Plan) é que tem a permissão para fazer isso.<br>Isto implica que caso você queira enviar requisições à Algolia/ElasticSearch através das Cloud Functions, você precisa adicionar o seu cartão de crédito e optar por um dos planos pagos.</p><p>Adicionar um cartão de crédito não deve ser problema para alguns, até porque mesmo depois de adicionar, eles não irão cobrar-lhe nada até que atinja um certo limite (conheça os limites na <a href="https://firebase.google.com/pricing/">tabela de preços</a>) e este limite é alto o suficiente para que uma aplicação de pequena escala não o atinja em pouco tempo.</p><p>Mas por outro lado, existem desenvolvedores que não pretendem utilizar estes planos, mesmo porque provavelmente não utilizarão nem metade das funcionalidades oferecidas ou porque estão a desenvolver apenas um protótipo. Foi a pensar nestes desenvolvedores que decidi criar uma forma de fazer a Pesquisa de Texto no plano grátis (Spark).</p><h3>Tocha — Pesquisas de Texto no Plano Spark</h3><p><a href="https://github.com/rosariopfernandes/Tocha">Tocha</a> é uma biblioteca Open Source, por mim desenvolvida, que permite fazer pesquisas de texto no Cloud Firestore e na Realtime Database mesmo que o seu projeto ainda esteja no plano grátis (Spark). É ideal para protótipos ou pequenas aplicações Android/iOS. <br>E tal como as outras soluções de pesquisa de texto para o Firebase, esta biblioteca funciona através de Cloud Functions.</p><h4>Como começar</h4><p>Vou assumir que você já sabe criar e fazer o deploy de Cloud Functions. Caso não, leia o <a href="https://medium.com/@rosariopfernandes/fcf-comecar-32c984dbc12">segundo artigo</a> desta série.</p><ol><li>No directório functions do seu projeto Firebase, abra o ficheiro <em>package.json</em> e certifique-se que a sua cloud function está a utilizar o NodeJS na versão 8:</li></ol><pre>{<br>  // ... name, description, dependencies, etc<br>  <strong>&quot;engines&quot;</strong>: {<br>    <strong>&quot;node&quot;</strong>: <strong>&quot;8&quot;</strong><br>  }<br>}</pre><p>2. Instale o Tocha, abrindo a terminal e utilizando o comando:</p><pre><strong>npm install tocha</strong></pre><p>3. Por fim, abra o ficheiro index.js do directório functions e importe a(s) funcionalidade(s) do Tocha que você precisa:</p><pre>const functions = require(&#39;firebase-functions&#39;);</pre><pre>// ... você pode importar mais bibliotecas aqui ...</pre><pre><strong>const tocha = require(&#39;tocha&#39;);</strong><br><br>// Para importar Pesquisa de texto no Cloud Firestore:<br><strong>exports.searchFirestore = tocha.searchFirestore;</strong><br><br>// Para importar Pesquisa de texto na Realtime Database:<br><strong>exports.searchRTDB = tocha.searchRTDB;</strong><br><br>// ... você pode declarar mais funções aqui ...</pre><p>E pronto. Agora só basta fazer o deploy das novas funções:</p><pre><strong>firebase deploy --only functions</strong></pre><h4>Vamos Experimentar</h4><p>Suponhamos que temos uma collection no Cloud Firestore que armazena tarefas para uma app de organização de tarefas. Vamos chamar esta collection de “tarefas”:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/568/1*OGS3nzYAVva2qT4JRuSxzg.png" /><figcaption>A collection tarefas e um dos documentos que ela contem.</figcaption></figure><p>Como vemos na imagem, a collection tem apenas 2 documentos, mas vamos supor que já tenhamos armazenado centenas de tarefas e já não nos lembramos à quem tínhamos de ligar para felicitar.<br>Vamos então utilizar o Tocha para pesquisar por tarefas que tenham a palavra “Ligar” no título. Para isso, temos de criar uma nova collection com o nome “tocha_searches”. Nesta collection vamos adicionar o seguinte documento:</p><pre>{<br>  &quot;collectionName&quot;: &quot;tarefas&quot;, // collection que vamos pesquisar<br>  &quot;fields&quot;: [&quot;titulo&quot;], // campo(s) a pesquisar<br>  &quot;query&quot;: &quot;Ligar*&quot; // texto a ser encontrado<br>}</pre><p>Ao adicionar este documento, a nossa Cloud Function será invocada e se estiver tudo correto, ela irá adicionar um campo response ao nosso documento contendo:</p><ul><li><strong>isSuccessful </strong>(boolean) — este campo terá o valor true se a nossa pesquisa for bem sucedida ou false caso contrário.</li><li><strong>result </strong>— se a pesquisa for bem sucedida, este campo será um array contendo as tarefas que foram encontradas como resultado da pesquisa. <strong>Nota:</strong> Se ocorrer algum erro e isSuccessful for false, o campo result não existirá.</li><li><strong>errorMessage</strong> — só existe se tiver ocorrido algum erro e o valor do campo é uma String explicando a causa do erro.</li></ul><p>Então a nossa resposta ficará algo como:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/462/1*_DXBKv3evYr_57PchGgKgg.png" /></figure><p>Num cenário real, só teríamos de ler o valor deste campo result e mostrá-lo na UI da nossa aplicação Android/iOS. E pronto, pesquisa implementada com sucesso.</p><h4>Limitações</h4><p>Tocha ainda é um projeto em desenvolvimento e possui algumas limitações:</p><ol><li>Firestore/RTDB Security Rules não se aplicam na pesquisa. Isto significa que todas pesquisas realizadas assumem que o utilizador autenticado é administrador e tem acesso à toda base de dados.</li><li>Ainda não existe um SDK client-side para executar a pesquisa, mas já comecei a desenvolver um para android(<a href="https://github.com/rosariopfernandes/tocha-android">tocha-android</a>).</li></ol><p>Vale lembrar que é um projeto Open Source, então você também é convidado à contribuir 🙂 O código-fonte e mais informações podem ser encontrados no GitHub:</p><p><a href="https://github.com/rosariopfernandes/tocha">rosariopfernandes/Tocha</a></p><p>Espero que esta biblioteca ajude-o no desenvolvimento de protótipos e/ou pequenas aplicações móveis com pesquisa de texto no Firebase. 🙂</p><p>Caso tenha alguma dúvida ou sugestão, deixe abaixo nos comentários. Se você estiver tentando usar a Tocha e teve algum problema, <a href="https://github.com/rosariopfernandes/Tocha/issues/new">abra um issue</a> no GitHub explicando o que você fez e qual foi o erro que teve.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7fd744b60dee" width="1" height="1" alt=""><hr><p><a href="https://medium.com/android-dev-moz/fcf-search-7fd744b60dee">Firebase Cloud Functions — Pesquisa de Texto na Base de dados</a> was originally published in <a href="https://medium.com/android-dev-moz">GDG Maputo</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Como funcionam as regras de segurança do Firebase na Realtime Database?]]></title>
            <link>https://medium.com/android-dev-moz/fbs4-8c45c9457c9?source=rss-60764aad5eb3------2</link>
            <guid isPermaLink="false">https://medium.com/p/8c45c9457c9</guid>
            <category><![CDATA[desenvolvimento-software]]></category>
            <category><![CDATA[medium-moçambique]]></category>
            <category><![CDATA[medium-em-português]]></category>
            <category><![CDATA[firebase]]></category>
            <category><![CDATA[seguranca-na-internet]]></category>
            <dc:creator><![CDATA[Rosário Pereira Fernandes]]></dc:creator>
            <pubDate>Mon, 29 Oct 2018 16:56:01 GMT</pubDate>
            <atom:updated>2018-10-29T16:56:01.227Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*FiOk3gqNFoavQW8n4vO7Fw.png" /></figure><h4>Parte 4 — Testes Unitários</h4><p>Na <a href="https://medium.com/@rosariopfernandes/fbs3-531abda78169">parte 3</a> desta série de artigos mostrei como utilizar o Simulador de Regras da Realtime Database. O simulador é uma ferramenta muito útil e que ajuda bastante na hora de testar as nossas regras online.</p><p>Mas hoje, durante o <a href="http://firebase.google.com/summit">Firebase Summit 2018</a>, foram lançadas 2 novas ferramentas que ajudam também na hora de testar regras: o<strong> </strong><a href="https://firebase.google.com/docs/database/security/test-rules-emulator"><strong>Emulador da Realtime Database</strong></a> e o módulo <strong>firebase-testing</strong> da Firebase CLI. Neste artigo mostro como funcionam estas ferramentas e como elas facilitam-nos quando queremos verificar o comportamento das nossas regras de segurança.</p><h3>Realtime Database Emulator</h3><p>O emulador da Realtime Database é uma ferramenta que permite simular uma instância de uma database na nossa máquina local. Todas as operações que executamos na nossa Realtime Database podem ser simuladas localmente no emulador. A única diferença é que o emulador não está interligado aos outros serviços do Firebase.</p><h4>Instalação</h4><p>Para instalar o emulador, temos de executar os seguintes comandos:</p><pre>firebase --open-sesame emulators<br>firebase setup:emulators:database</pre><h4>Iniciar</h4><p>Agora que temos o emulador instalado, podemos iniciá-lo usando o comando: firebase serve --only firestore. Ao introduzir o comando, deverá aparecer uma mensagem dizendo “Listening on port 9000” no seu ecrã.</p><p>Geralmente a Realtime Database pode ser acedida através da URL https://&lt;nome-da-database&gt;.firebaseio.com/caminho/dos/dados.json. Ao iniciar o emulador, a mesma database pode ser acedida também pela URL http://localhost:9000/caminho/dos/dados.json?ns=&lt;nome-da-database&gt;.</p><p>Quando você inicia o emulador, a realtime database simulada é criada com as regras privadas (.write e .read em false).</p><h3>Módulo node.js firebase-testing</h3><p>Este módulo permite-nos escrever testes unitários para a nossa database. Neste artigo, vamos criar um diretório chamado teste, e neste diretório vamos instalar o nosso módulo firebase-testing. Para isso, basta utilizarmos o comando:</p><pre>npm install --save @firebase/testing</pre><h4>async/await</h4><p>Antes de começarmos a escrever os testes unitários, há 2 conceitos que podem ser novos para você: <strong>async</strong> e <strong>await</strong>.</p><p>Você já deve saber que as funções de leitura e escrita do Firebase <a href="https://pt.stackoverflow.com/a/278696/39181">funcionam de forma assíncrona</a>. Mas como os nossos testes serão executados em sequência, não podemos fazê-los de forma assíncrona, pois a sequência se perderá.</p><p>E para nos ajudar com isso, o JavaScript possui o async e o await que permitem-nos esperar pelo resultado de uma operação antes de ir para a próxima. Por exemplo, para ler um utilizador de forma assíncrona no JavaScript, você faria:</p><pre>function lerUtilizador(uid)<br>{<br>  rootRef.child(&quot;utilizadores&quot;).child(uid).once(&#39;value&#39;, function(snapshot){<br>      var utilizador = snapshot.val();<br>      //Mostrar o utilizador<br>  });<br>}</pre><p>Para fazer a mesma leitura, de forma síncrona, você deve fazer:</p><pre><strong>async</strong> function lerUtilizador(uid)<br>{<br>  var snapshot = <strong>await</strong> rootRef.child(&quot;utilizadores&quot;).child(uid).once(&#39;value&#39;);<br>  var utilizador = snapshot.val();<br>  //Mostrar o utilizador<br>}</pre><p>Há uma coisa a notar: o async serve para anotar funções e o await só pode ser utilizado em funções que foram declaradas com a anotação async.</p><p>Você pode aprender mais sobre async e await <a href="https://medium.com/@pedrodava/javascript-101-async-await-50a0428a0929">neste post</a> do <a href="https://medium.com/u/58a6ee125066">Jose Pedro Dava</a>.</p><h4>Escrever Testes Unitários</h4><p>Para escrever os nossos testes, o firebase-testing possui as funções:</p><ul><li><strong>initializeTestApp</strong>({ databaseName, auth }) — simula uma app que está a ser acedida por um utilizador autenticado, que é especificado no parâmetro auth.</li><li><strong>initializeAdminApp</strong>({ databaseName }) — simula uma app que está ser acedida com privilégios de administrador (é como usar o Admin SDK ou a REST API para aceder à database).</li><li><strong>loadRules</strong>({ databaseName , rulesPath }) — carrega as regras de segurança que iremos testar.</li><li><strong>apps</strong>() — retorna a lista de todos as apps que foram inicializadas para simulação.</li><li><strong>assertFails</strong>(pr: Promise) — verifica se uma escrita/leitura irá falhar.</li><li><strong>assertSucceeds</strong>(pr: Promise) — verifica se uma escrita/leitura irá ser executada com sucesso.</li></ul><p>Agora que conhecemos as funções, podemos então escrever testes unitários para as regras (veja <a href="https://gist.github.com/rosariopfernandes/1ec0d39cd0322a4b13edb6a5ace1decb">database.rules.json</a>) da database que temos usado durante esta série de artigos (veja <a href="https://gist.github.com/rosariopfernandes/d9af6a5c5aca7caf0c5471bfef8771ea#file-mydatabase-json">MyDatabase.json</a>).</p><p>Por exemplo, uma regra que definimos foi: <em>“Utilizadores só podem enviar mensagens para grupos que fazem parte”</em>. A regra escrita foi:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/541bf1e7f84632226b2bb0b3abd18800/href">https://medium.com/media/541bf1e7f84632226b2bb0b3abd18800/href</a></iframe><p>E o código JavaScript para enviar a mensagem seria algo como:</p><pre>rootRef.child(“mensagens/g1”).push().set(“Olá Mundo!”);</pre><p>Então usamos este mesmo código simulando um utilizador autenticado. Podemos verificar se o utilizador de uid=”uid1&quot; pode realmente escrever no grupo com a chave “g1” (que ele faz parte):</p><pre>let firebase = require(&quot;<a href="http://twitter.com/firebase/testing">@firebase/testing</a>&quot;);</pre><pre>let app = firebase.initializeTestApp({ databaseName: &quot;MinhaDB&quot;, auth: {uid:&quot;uid1&quot;} });</pre><pre>await firebase.assertSucceeds(app.database().ref(&quot;mensagens/g1&quot;).push().set(&quot;Olá Mundo&quot;));</pre><p>E podemos nos certificar que ele não tem acesso ao grupo “g2”:</p><pre>await firebase.assertFails(app.database().ref(&quot;mensagens/g2&quot;).push().set(&quot;Olá Mundo&quot;));</pre><p>Juntando os dois, o nosso ficheiro index.js(no directório teste) ficaria assim:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b198b4f435a2bea2d2bf3782b820d3c2/href">https://medium.com/media/b198b4f435a2bea2d2bf3782b820d3c2/href</a></iframe><p>Este é um dos exemplos mais simples. Completei o ficheiro index.js para testar todas as regras que foram definidas, e ficou assim:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/180695accec5303e9728478ae66ce4f4/href">https://medium.com/media/180695accec5303e9728478ae66ce4f4/href</a></iframe><p>Depois de escrever os testes, temos de executá-los. Para isso, voltamos à terminal e (no diretório parente do diretório teste) executamos o comando npm test teste. Você deverá ter um output semelhante à este:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/814/1*AH1yajM6wSHkRjZqieahLw.png" /></figure><p>E por hoje é tudo. Espero que você tenha compreendido e que comece também a escrever testes unitários para a sua database. ;)</p><p>Caso tenha alguma dúvida ou sugestão, deixe abaixo nos comentários. Se você estiver tentando escrever testes unitários e teve um problema, <a href="https://pt.stackoverflow.com/questions/ask?tags=firebase">coloque ele no StackOverflow</a>, mostrando o que você fez e qual foi o erro que teve. De certeza que você obterá ajuda de mim ou de alguém da comunidade. 🙂</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8c45c9457c9" width="1" height="1" alt=""><hr><p><a href="https://medium.com/android-dev-moz/fbs4-8c45c9457c9">Como funcionam as regras de segurança do Firebase na Realtime Database?</a> was originally published in <a href="https://medium.com/android-dev-moz">GDG Maputo</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Apresentando o fireXtensions]]></title>
            <link>https://medium.com/android-dev-moz/firektx-2fc1651d095e?source=rss-60764aad5eb3------2</link>
            <guid isPermaLink="false">https://medium.com/p/2fc1651d095e</guid>
            <category><![CDATA[medium-em-português]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[medium-moçambique]]></category>
            <category><![CDATA[firebase]]></category>
            <category><![CDATA[kotlin]]></category>
            <dc:creator><![CDATA[Rosário Pereira Fernandes]]></dc:creator>
            <pubDate>Wed, 05 Sep 2018 16:56:02 GMT</pubDate>
            <atom:updated>2019-09-29T18:30:04.938Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*sZ9hPBXaot4xmaZr1NYYTg.png" /></figure><h4>Mudando a forma como você utiliza o Firebase no Android</h4><p><strong>ATUALIZAÇÃO 29/09/2019: O fireXtensions foi descontinuado a favor das </strong><a href="https://firebaseopensource.com/projects/firebase/firebase-android-sdk/#kotlin_extensions"><strong>bibliotecas KTX oficiais do Firebase</strong></a><strong>. Obrigado a todos que contribuiram, apoiaram ou utilizaram o fireXtensions.</strong></p><p>18 de Maio de 2017 foi o dia em que a Google anunciou, durante o Google I/O, que <a href="https://developer.android.com/kotlin/">Kotlin</a> passa a ser (oficialmente) uma linguagem para desenvolvimento de aplicações Android. Isso porque:</p><blockquote>Kotlin is expressive, concise, and powerful.<br>(Kotlin é expressivo, conciso e poderoso)</blockquote><p>Essa foi uma das melhores novidades do I/O, pois esta linguagem traz várias funcionalidades que facilitam a vida dos desenvolvedores e de certa forma melhora a produtividade deles. Se você não conhece as funcionalidades da linguagem, recomendo que leia esta série de artigos do <a href="https://medium.com/u/bda34d240011">Paulo Enoque</a>:</p><ol><li><a href="https://medium.com/kotlin-para-android/introdu%C3%A7%C3%A3o-a-kotlin-51a4355f3bc8">Introdução a Kotlin</a></li><li><a href="https://medium.com/kotlin-para-android/sintaxe-b%C3%A1sica-do-kotlin-7548a441f5e5">Sintaxe básica do Kotlin</a></li><li><a href="https://medium.com/kotlin-para-android/detalhes-avan%C3%A7ados-sobre-kotlin-c0a9b0059880">Detalhes avançados sobre Kotlin</a></li><li><a href="https://medium.com/kotlin-para-android/kotlin-android-extensions-8abdc33f21ef">Kotlin Android Extensions</a></li></ol><h3>Kotlin Extensions</h3><p>Uma funcionalidade que, em particular, chamou a minha atenção foi <a href="https://kotlinlang.org/docs/reference/extensions.html">Kotlin Extensions</a>. Esta funcionalidade permite que você adicione novos métodos à classes que não são suas, sem ter de herdar (o famoso extends do java) dessa classe. Por exemplo: eu posso criar um método que verifica se uma String contém ponto de exclamação(!), algo como:</p><pre>fun contemPontoExclamacao(umaString: String): Boolean {<br>    return umaString.contains(&#39;!&#39;)<br>}</pre><p>Mas para usar o método, eu tenho de chamar da seguinte forma: contemPontoExclamacao(&quot;Olá Mundo!&quot;). Isso parece ok, mas imagine se eu tiver de chamar o método em várias classes — teria de declarar o método em todas elas ou declará-lo em uma só classe e definí-lo como estático. Ou até criar uma classe MinhaString que herda da classe String e implementa o método contemPontoExclamacao(). Depois teria de mudar o tipo de dado de todas as Strings do meu programa para que passasse a ser do tipoMinhaString.</p><p>Utilizando Kotlin Extensions, eu posso fazer com que este método faça parte da classe String:</p><pre>fun <strong>String</strong>.contemPontoExclamacao(): Boolean{<br>    return contains(&#39;!&#39;)<br>}</pre><p>E então posso chamá-lo em qualquer classe, sempre da mesma forma:</p><pre>&quot;Olá Mundo!&quot;.contemPontoExclamacao()<br>// ou:<br>val frase = &quot;Olá Mundo&quot;<br>frase.contemPontoExclamacao()</pre><p>Como você pode ver, Kotlin simplifica o código que temos de escrever. Muitos desenvolvedores (a google inclusive) aproveitaram disso para desenvolver bibliotecas que tornam o desenvolvimento Android mais simples. Falo de bibliotecas como <a href="https://developer.android.com/kotlin/ktx">Android KTX</a>, <a href="https://github.com/Kotlin/anko">Anko</a>, <a href="https://github.com/PauloEnoque/Nahu">Nahu</a>, entre outras.</p><h3>FireXtensions</h3><p>Foi inspirado nessas bibliotecas que decidi desenvolver o <a href="https://firebaseopensource.com/projects/rosariopfernandes/firextensions/"><strong>fireXtensions</strong></a>. fireXtensions é uma biblioteca que vem para simplificar a forma como nós (desenvolvedores) executamos operações no Firebase. Atualmente, a biblioteca suporta a Realtime Database e Cloud Firestore.</p><p><strong>Por exemplo</strong>:<br>Para ler utilizadores da Realtime Database com Kotlin, você utilizaria o código:</p><pre>ref.addValueEventListener(object: ValueEventListener {<br>    override fun onDataChange(dataSnapshot: DataSnapshot) {<br>        val utilizadores = ArrayList&lt;Utilizador&gt;()<br>        for (snapshot in dataSnapshot.children) {<br>            val utilizador = dataSnapshot.getValue(Utilizador::class.java)<br>            utilizadores.add(utilizador!!)<br>        }<br>        // Mostrar os utilizadores na UI<br>    }<br><br>    override fun onCancelled(error: DatabaseError) {<br>        // Mostrar o erro<br>    }<br>})</pre><p>Com fireXtensions:</p><pre>ref.observeChildren&lt;Utilizador&gt; { utilizadores, error -&gt;<br>    utilizadores?.let {<br>        // Mostrar os utilizadores na UI<br>    }<br>    error.let {<br>        // Mostrar o erro<br>    }<br>}</pre><p>Fica mais simples, não é?</p><p><strong>Exemplo 2</strong>: Ler dados da cidade “Maputo que está na coleção “cidades” do Firestore:</p><pre>val docRef = db.collection(&quot;cidades&quot;).document(&quot;Maputo&quot;)<br>docRef.get().addOnCompleteListener { task -&gt;<br>    if (task.isSuccessful()) {<br>        val cidade = task.result.toObject(Cidade::class.java)<br>        // Mostrar a cidade<br>    }<br>}</pre><p>Com fireXtensions:</p><pre>docRef.getDocument&lt;Cidade&gt;() { cidade, _ -&gt;<br>    cidade?.let {<br>        // Mostrar a cidade<br>    }<br>}</pre><h4>Como fazer essa magia?</h4><p>Utilizar o fireXtensions na sua aplicação é muito simples, basta seguir as instruções encontradas no <a href="https://firebaseopensource.com/projects/rosariopfernandes/fireXtensions/">site</a>:</p><ol><li>Adicionar o maven do jitpack para o build.gradle do projecto:</li></ol><pre>allprojects {<br>        repositories {<br>            ...<br>            maven { url &#39;https://jitpack.io&#39; }<br>        }<br>}</pre><p>2. Adicionar a dependência ao build.gradle da app. Aqui você tem 2 opções:</p><ul><li>Adicionar as extensions para Realtime Database <strong>e</strong> Cloud Firestore:</li></ul><pre>dependencies {<br>        implementation &#39;com.github.rosariopfernandes:fireXtensions:0.3.4&#39;<br>}</pre><ul><li>Ou adicionar as extensions só para Realtime Database <strong>ou</strong> só para Cloud Firestore:</li></ul><pre>dependencies {</pre><pre>        // Use apenas uma:<br>        // Importar só a database<br>        implementation &#39;com.github.rosariopfernandes.fireXtensions:database:0.3.4&#39;<br><br>        // ou importar só o firestore<br>        implementation &#39;com.github.rosariopfernandes.fireXtensions:firestore:0.3.4&#39;<br>}</pre><p>Conheça todas as extensions oferecidas pela biblioteca nos tutoriais:</p><ul><li><a href="https://firebaseopensource.com/projects/rosariopfernandes/firextensions/tutorials/realtime-database.md/">Realtime Database</a>;</li><li><a href="https://firebaseopensource.com/projects/rosariopfernandes/firextensions/tutorials/cloud-firestore.md/">Cloud Firestore</a>.</li></ul><h4>Contribuir para a biblioteca</h4><p>fireXtensions é open source (sob a <a href="https://github.com/rosariopfernandes/fireXtensions/blob/master/LICENSE.md">MIT License</a>) e você pode contribuir no <a href="https://github.com/rosariopfernandes/fireXtensions">GitHub</a>. <a href="https://github.com/rosariopfernandes/fireXtensions/issues/new">Abra um issue</a> para sugerir uma alteração, pode ser uma nova funcionalidade ou correção de bugs. Se a sua alteração for aprovada, aí você poderá mandar um Pull Request para fazê-la ou esperar que alguém o faça.</p><p>Espero que esta biblioteca simplifique a forma como você escreve o seu código Android e que ajude-lhe a melhorar a sua produtividade. 🙂 Caso tenha alguma dúvida ou sugestão, deixe abaixo nos comentários. Se você estiver tentando usar o fireXtensions e teve um problema, <a href="https://github.com/rosariopfernandes/fireXtensions/issues/new">abra um issue</a> no GitHub explicando o que você fez e qual foi o erro que teve.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2fc1651d095e" width="1" height="1" alt=""><hr><p><a href="https://medium.com/android-dev-moz/firektx-2fc1651d095e">Apresentando o fireXtensions</a> was originally published in <a href="https://medium.com/android-dev-moz">GDG Maputo</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>