<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Renato Almeida - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Aprenda a codificar - de graça. Tutoriais de programação em Python, JavaScript, Linux e muito mais. ]]>
        </description>
        <link>https://www.freecodecamp.org/portuguese/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Renato Almeida - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/portuguese/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sat, 30 May 2026 13:56:23 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/portuguese/news/author/renato/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Como implantar uma aplicação com MERN no Heroku usando o MongoDB Atlas ]]>
                </title>
                <description>
                    <![CDATA[ Introdução ao MERN Neste artigo, construiremos e implantaremos uma aplicação criada com a stack  MERN no Heroku. MERN, que significa MongoDB, Express, React e Node.js, é uma stack  (literalmente, em português, pilha – mas que podemos traduzir como "conjunto de tecnologias") popular usada na construção de aplicações para ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-implantar-uma-aplicacao-com-mern-no-heroku-usando-o-mongodb-atlas/</link>
                <guid isPermaLink="false">652d1efab73e2e03f70cea51</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Renato Almeida ]]>
                </dc:creator>
                <pubDate>Wed, 03 Jul 2024 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/1_qgxaya.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/deploying-a-mern-application-using-mongodb-atlas-to-heroku/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Deploy a MERN Application to Heroku Using MongoDB Atlas</a>
      </p><h2 id="introdu-o-ao-mern">Introdução ao MERN</h2><p>Neste artigo, construiremos e implantaremos uma aplicação criada com a <em>stack</em> MERN no Heroku.</p><p>MERN, que significa MongoDB, Express, React e Node.js, é uma <em>stack</em> (literalmente, em português, pilha – mas que podemos traduzir como "conjunto de tecnologias") popular usada na construção de aplicações para a web. Ela envolve trabalho de <em>front-end</em> (com React), trabalho de <em>back-end</em> (com Express e NodeJS) e um banco de dados (com MongoDB).</p><p>O <a href="https://www.heroku.com/">Heroku</a>, por outro lado, é uma plataforma como serviço (PaaS) que permite aos desenvolvedores criar, executar e operar aplicações inteiramente na nuvem.</p><blockquote>Nota da tradução: até pouco tempo atrás, o Heroku dispunha de um espaço gratuito para essas implementações. Hoje em dia, mesmo a camada mais básica da plataforma vem com um custo.</blockquote><p>Para o banco de dados, usaremos o MongoDB Atlas, que é um serviço global de banco de dados em nuvem para aplicações modernas. É mais seguro do que ter o MongoDB instalado localmente em nosso servidor e também nos dá espaço para mais recursos em nossos servidores.</p><p>Para o <em>front-end</em>, construiremos uma aplicação em React simples, que faz solicitações POST a uma API para adicionar um usuário, também podendo fazer solicitações GET para obter todos os usuários.</p><p><em>Você pode pular para qualquer etapa com o índice listado abaixo.</em></p><h2 id="-ndice">Índice</h2><ul><li>Introdução ao MERN</li><li>Vamos começar a criar</li><li>Construindo a aplicação em React</li><li>Criando o <em>back-end</em></li><li>Conectando o banco de dados do MongoDB Atlas</li><li>Chamando APIs no <em>front-end</em></li><li>Implantando no Heroku</li><li>Criando uma aplicação no Heroku</li><li>Configurando o <em>package.json</em></li><li>Resumo</li></ul><h2 id="vamos-come-ar-a-criar">Vamos começar a criar</h2><h3 id="construindo-a-aplica-o-em-react">Construindo a aplicação em React</h3><p><strong>Nota</strong>: antes de começarmos nosso projeto, o <code>node</code> deve estar instalado em seu computador. O <code>node</code> também nos fornece o <code>npm</code>, que é usado para instalar pacotes.</p><h3 id="instalando-o-create-react-app">Instalando o create-react-app</h3><p>O <code>create-react-app</code> é usado para criar uma aplicação inicial em React.</p><blockquote>Nota da tradução: mais recentemente, surgiram alternativas ao <code>create-react-app</code> que consomem menos espaço e são mais práticas para a criação de aplicações em React, como o <a href="https://vitejs.dev/">Vite</a>. O <code>create-react-app</code>, no entanto, segue sendo uma boa alternativa em termos didáticos para quem está começando a aprender.</blockquote><p>Se você não tiver o <code>create-react-app</code> instalado, digite o seguinte na linha de comando:</p><pre><code class="language-shell">npm i create-react-app -g</code></pre><p>O parâmetro <code>-g</code> instala o pacote globalmente.</p><h3 id="criando-o-diret-rio-do-projeto">Criando o diretório do projeto</h3><pre><code class="language-shell">create-react-app my-project
cd my-project</code></pre><p>O primeiro comando acima cria um diretório "my-project" e instala as dependências que serão usadas na aplicação inicial em React. Após terminar a instalação, o segundo comando muda para o diretório do projeto.</p><h3 id="iniciando-a-aplica-o-e-fazendo-as-edi-es-necess-rias">Iniciando a aplicação e fazendo as edições necessárias</h3><pre><code class="language-shell">npm start</code></pre><p>O comando acima inicia a aplicação React, que fornece um URL onde você visualiza o projeto. Você pode, então, fazer as edições necessárias, como alterar imagens ou texto.</p><h3 id="instalando-o-axios">Instalando o axios</h3><pre><code class="language-shell">npm i axios --save</code></pre><p>O <code>axios</code> é uma biblioteca do JavaScript usada para facilitar requisições HTTP. Ele será usado para enviar requisições do <em>front-end</em> (React) para as APIs fornecidas pelo <em>back-end</em>.</p><h3 id="criando-o-back-end">Criando o <em>back-end</em></h3><p>O <em>back-end</em> gerencia as APIs, lida com requisições e também se conecta ao banco de dados.</p><h3 id="instalando-os-pacotes-de-back-end">Instalando os pacotes de <em>back-end</em></h3><pre><code class="language-shell">npm i express cors mongoose body-parser --save</code></pre><ol><li><code>express</code>: "O Express é uma infraestrutura para aplicações da web em Node.js mínima e flexível, que fornece um conjunto robusto de recursos para essas aplicações para a web" – <a href="http://expressjs.com/">documentação do Express</a> (em inglês)</li><li><code>cors</code>: "O CORS é um pacote do Node.js para fornecer um <em>middleware</em> para Connect/Express que pode ser usado para habilitar o CORS com várias opções" – <a href="https://www.npmjs.com/package/cors">documentação do CORS</a> (em inglês)</li><li><code>mongoose</code>: "O Mongoose é uma ferramenta de modelagem de objetos para MongoDB projetada para funcionar em um ambiente assíncrono. O Mongoose suporta <em>promises</em> e funções de <em>callback</em> (retornos de chamada)" – <a href="https://www.npmjs.com/package/mongoose">documentação do Mongoose</a></li><li><code>body-parser</code>: "O <em>middleware</em> de análise (e transformação dos dados) do <em>body</em> para o Node.js." – <a href="https://www.npmjs.com/package/body-parser">documentação do body-parser</a> (em inglês)</li></ol><blockquote>Nota da tradução: <code>body-parser</code> foi descontinuado. A análise e a transformação dos dados, agora, pode ser feita diretamente pelo Express.</blockquote><h3 id="criando-a-pasta-de-back-end">Criando a pasta de <em>back-end</em></h3><pre><code class="language-shell">mkdir backend
cd backend</code></pre><h3 id="configurando-o-back-end">Configurando <em>o back-end</em></h3><p><strong>Criando um ponto de entrada (<em>entry point</em>)</strong> <code>server.js</code></p><p>Primeiro, crie um arquivo <code>server.js</code>, que será o ponto de entrada para o <em>back-end</em>.</p><pre><code class="language-shell">touch server.js</code></pre><p>No arquivo <code>server.js</code>, digite o seguinte:</p><pre><code class="language-js">const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const path = require('path')
const app = express();
require('./database');
-----
app.use(bodyParser.json());
app.use(cors());
-----
// API
const users = require('/api/users');
app.use('/api/users', users);
-----
app.use(express.static(path.join(__dirname, '../build')))
app.get('*', (req, res) =&gt; {
    res.sendFile(path.join(__dirname, '../build'))
})
-----
const port = process.env.PORT || 5000;
app.listen(port, () =&gt; {
    console.log(`Server started on port ${port}`);
});</code></pre><p><code>express.static</code> fornece arquivos estáticos que são aqueles construídos quando <code>npm run build</code> é executado em um projeto do React. Lembre-se de que o arquivo compilado está na pasta <code>build</code>.</p><p>A partir da nossa configuração, qualquer requisição enviada para <code>/api/users</code> será enviada para a API <code>users</code> que estamos prestes a configurar.</p><p><strong>Configurando a API </strong><code>users</code></p><pre><code class="language-shell">mkdir api
touch api/users.js</code></pre><p>No arquivo <code>api/users.js</code>, adicione o seguinte:</p><pre><code class="language-js">const express = require('express');
const router = express.Router()
-----
const User = require('../models/User');
-----
router.get('/', (req, res) =&gt; {
    User.find()
        .then(users =&gt; res.json(users))
        .catch(err =&gt; console.log(err))
})
-----
router.post('/', (req, res) =&gt; {
    const { name, email } = req.body;
    const newUser = new User({
        name: name, email: email
    })
    newUser.save()
        .then(() =&gt; res.json({
            message: "Created account successfully"
        }))
        .catch(err =&gt; res.status(400).json({
            "error": err,
            "message": "Error creating account"
        }))
})
module.exports = router </code></pre><p>No código acima, criamos um manipulador de requisições GET e POST, que busca todos os usuários e os publica. Buscar e adicionar um usuário ao banco de dados é auxiliado pelo modelo <code>User</code> que criaremos.</p><p><strong>Criando o modelo</strong> <code>User</code></p><pre><code class="language-shell">mkdir models
touch models/user.js</code></pre><p>No arquivo <code>models/user.js</code>, adicione o seguinte:</p><pre><code class="language-js">const mongoose = require('mongoose');
const Schema = mongoose.Schema;
-----
const userSchema = new Schema({
    name: {
        type: String,
        required: true
    },
    email: {
        type: String,
        required: true
    }
})
module.exports = mongoose.model("User", userSchema, "users")</code></pre><p>No código acima, é criado um esquema para o usuário que contém os campos do usuário. Ao final do arquivo, o modelo ("User") é exportado com o esquema e a coleção ("users").</p><h3 id="conectando-o-banco-de-dados-do-mongodb-atlas">Conectando o banco de dados do MongoDB Atlas</h3><p>De acordo com <a href="https://www.mongodb.com/cloud/atlas">a documentação</a> (em inglês), "o MongoDB Atlas é o serviço global de banco de dados em nuvem para aplicações modernas".</p><p>Primeiro, precisamos nos registrar no <em>MongoDB Cloud</em>. Consulte <a href="https://docs.atlas.mongodb.com/getting-started/">esta documentação</a> (em inglês) para criar uma conta do Atlas e criar seu <em>cluster</em>.</p><p>Uma coisa que vale a pena observar é <strong>colocar o endereço IP de sua conexão na lista de permissões</strong>. Se você ignorar essa etapa, não terá acesso ao <em>cluster</em>, portanto preste atenção nessa parte.</p><p>O <em>cluster</em> é um pequeno servidor que gerenciará nossas coleções (semelhante às tabelas em bancos de dados do SQL). Para conectar seu <em>back-end</em> ao cluster, crie um arquivo <code>database.js</code>, que, como você pode ver, é necessário em <code>server.js</code>. Em seguida, digite o seguinte:</p><pre><code class="language-javascript">const mongoose = require('mongoose');
const connection = "mongodb+srv://username:&lt;password&gt;@&lt;cluster&gt;/&lt;database&gt;?retryWrites=true&amp;w=majority";
mongoose.connect(connection,{ useNewUrlParser: true, useUnifiedTopology: true, useFindAndModify: false})
    .then(() =&gt; console.log("Database Connected Successfully"))
    .catch(err =&gt; console.log(err));</code></pre><p>Na variável de conexão, insira seu <code>nome de usuário</code> (para o <em>MongoDB Cloud</em>), sua <code>senha</code> (senha do cluster), seu <code>cluster</code> (endereço do seu cluster) e o <code>banco de dados</code> (nome do seu banco de dados). Tudo isso pode ser facilmente descoberto se você seguir a documentação.</p><h2 id="chamando-apis-no-front-end">Chamando APIs no <em>front-end</em></h2><p>Todas as APIs estarão disponíveis localmente em <code>localhost:5000</code>, assim como configuramos no <code>server.js</code>. Quando implantado no Heroku, o servidor usará a porta fornecida pelo servidor <code>(process.env.PORT)</code>.</p><p>Para facilitar as coisas, o React nos permite especificar um <em>proxy </em>para o qual as solicitações serão enviadas.</p><p>Abra o <code>package.json</code> e, logo antes da última chave, adicione o seguinte:</p><pre><code class="language-json">"proxy": "http://localhost:5000"</code></pre><p>Desse modo, podemos enviar solicitações diretamente para <code>api/users</code>. Quando nosso site for implantado e criado, a porta padrão da nossa aplicação será usada com a mesma API.</p><p>Abra <code>App.js</code> para o React e adicione o seguinte:</p><pre><code class="language-javascript">import React, {useState, useEffect} from 'react'
import axios from 'axios';
-----
const App = function () {
	const [users, setUsers] = useState(null);

	const [username, setUsername] = useState("");
	const [email, setEmail] = useState("");
	useEffect(() =&gt; {
		axios
			.get("/api/users")
			.then((users) =&gt; setUsers(users))
			.catch((err) =&gt; console.log(err));
	}, []);

	function submitForm() {
		if (username === "") {
			alert("Please fill the username field");
			return;
		}
		if (email === "") {
			alert("Please fill the email field");
			return;
		}
		axios
			.post("/api/users", {
				username: username,
				email: email,
			})
			.then(function () {
				alert("Account created successfully");
				window.location.reload();
			})
			.catch(function () {
				alert("Could not creat account. Please try again");
			});
	}
	return (
		&lt;&gt;
			&lt;h1&gt;My Project&lt;/h1&gt;
			{users === null ? (
				&lt;p&gt;Loading...&lt;/p&gt;
			) : users.length === 0 ? (
				&lt;p&gt;No user available&lt;/p&gt;
			) : (
				&lt;&gt;
					&lt;h2&gt;Available Users&lt;/h2&gt;
					&lt;ol&gt;
						{users.map((user, index) =&gt; (
							&lt;li key={index}&gt;
								Name: {user.name} - Email: {user.email}
							&lt;/li&gt;
						))}
					&lt;/ol&gt;
				&lt;/&gt;
			)}

			&lt;form onSubmit={submitForm}&gt;
				&lt;input
					onChange={(e) =&gt; setUsername(e.target.value)}
					type="text"
					placeholder="Enter your username"
				/&gt;
				&lt;input
					onChange={(e) =&gt; setEmail(e.target.value)}
					type="text"
					placeholder="Enter your email address"
				/&gt;
				&lt;input type="submit" /&gt;
			&lt;/form&gt;
		&lt;/&gt;
	);
};
export default App</code></pre><p>Os <em>hooks</em> <code>useState</code> e <code>useEffect</code> são usados ​​para manipular estados e efeitos colaterais <code>(sideEffects)</code>. O que basicamente está acontecendo é que o primeiro estado dos usuários é <code>null</code> e 'Loading...' (carregando) é mostrado no navegador.</p><p>No <code>useEffect[]</code>, <code>[]</code> é usado para especificar que, no estágio <code>componentDidMount</code> (quando o componente é montado), deve-se fazer uma solicitação do Axios para a API, que está sendo executada em <code>localhost:5000</code>. Se obtiver o resultado e não houver nenhum usuário, "<em>No user available</em>" (nenhum usuário disponível) será exibido. Caso contrário, será exibida uma lista numerada dos usuários.</p><p>Se você quiser saber mais sobre <code>useState</code> e <code>useEffect</code>, confira este artigo – <a href="https://blog.soshace.com/what-the-heck-is-react-hooks/">O que diabos são React Hooks?</a> (em inglês)</p><h2 id="implantando-no-heroku">Implantando no Heroku</h2><p>Para implantar sua aplicação no Heroku, você deve ter uma conta por lá.</p><p>Vá para <a href="https://www.heroku.com/">a página do Heroku</a> para criar uma conta. Em seguida, consulte <a href="https://devcenter.heroku.com/">a documentação</a> sobre como criar uma aplicação no Heroku. Verifique também <a href="https://devcenter.heroku.com/articles/heroku-cli">a documentação</a> do Heroku CLI. (links em inglês)</p><blockquote>Nota da tradução: reforçando, o Heroku não é mais gratuito. Caso seja sua intenção dar sequência a esse processo por lá, saiba que mesmo as alternativas iniciais agora são pagas.</blockquote><h3 id="criando-uma-aplica-o-no-heroku">Criando uma aplicação no Heroku</h3><p>Primeiro, faça login no Heroku:</p><pre><code class="language-shell">heroku login</code></pre><p>Isso vai redirecionar você para um URL no navegador onde você poderá fazer login. Quando terminar, você poderá continuar no terminal.</p><p>No mesmo diretório do projeto em React, execute o seguinte:</p><pre><code class="language-shell">heroku create</code></pre><p>Isso criará uma aplicação no Heroku e também fornecerá o URL para acessar o aplicativo.</p><h3 id="configurando-o-package-json">Configurando o package.json</h3><p>O Heroku usa seu arquivo <code>package.json</code> para saber quais scripts executar e quais dependências instalar para que seu projeto seja executado com sucesso.</p><p>No seu arquivo <code>package.json</code>, adicione o seguinte:</p><pre><code class="language-json">{
    ...
    "scripts": {
        ...
        "start": "node backend/server.js",
        "heroku-postbuild": "NPM_CONFIG_PRODUCTION=false npm install npm &amp;&amp; run build"
    },
    ...
    "engines": {
        "node": "10.16.0"
    }
}</code></pre><p>O Heroku executa uma pós-compilação que, como você poderá ver, instalará suas dependências e executará uma compilação do seu projeto em React. Em seguida, ele iniciará seu projeto com o script <code>start</code> que, basicamente, inicia seu servidor. Depois disso, seu projeto deverá funcionar bem.</p><p><code>engines</code> especifica as versões das <em>engines</em>, como <code>node</code> e <code>npm</code>, a serem instaladas.</p><h3 id="enviando-para-o-heroku">Enviando para o Heroku</h3><pre><code class="language-shell">git push heroku master</code></pre><p>O comando acima envia seu código para o Heroku. Lembre-se de incluir arquivos desnecessários em <code>.gitignore</code>.</p><p>Após alguns segundos, seu site estará pronto. Se houver algum erro, você pode verificar seu terminal ou acessar seu painel no navegador para visualizar os <em>logs</em> (registros) de criação (da <em>build</em>).</p><p>Agora, você pode visualizar seu site no URL que o Heroku enviou quando você executou <code>heroku create</code>.</p><p>Isso é tudo que há para fazer. Que bom que você chegou até aqui.</p><h2 id="resumo">Resumo</h2><p>É claro que há mais sobre aplicações da <em>stack</em> MERN.</p><p>Este artigo não se aprofundou em autenticações, login, sessões e tudo mais. Abordou apenas como implantar aplicações da <em>stack</em> MERN no Heroku e como trabalhar com MongoDB Atlas.</p><p>Você pode encontrar outros artigos como este no blog do autor: <a href="https://dillionmegida.com/">dillionmegida.com</a></p><p>Obrigado pela leitura.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como programar seu próprio emissor de eventos em Node.js: um guia passo a passo ]]>
                </title>
                <description>
                    <![CDATA[ Escrito por: Rajesh Pillai Entenda o funcionamento do Node programando pequenos pacotes/módulos Se você é novo no Node.js, há muitos tutoriais aqui no freeCodeCamp e em outros lugares. Você pode conferir meu artigo All about Core Node.JS [https://codeburst.io/all-about-core-nodejs-part-1-b9f4b0a83278] (em inglês), por exemplo. Sem mais delongas, vamos ao assunto em discussão: ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-programar-seu-proprio-emissor-de-eventos-no-node-js-um-guia-passo-a-passo/</link>
                <guid isPermaLink="false">643c4d1b84d2fb0595fd64a0</guid>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Renato Almeida ]]>
                </dc:creator>
                <pubDate>Tue, 20 Jun 2023 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2023/05/0_R0F_SNqsLvxWG99J.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/how-to-code-your-own-event-emitter-in-node-js-a-step-by-step-guide-e13b7e7908e1/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to code your own event emitter in Node.js: a step-by-step guide</a>
      </p><p>Escrito por: Rajesh Pillai</p><h3 id="entenda-o-funcionamento-do-node-programando-pequenos-pacotes-m-dulos">Entenda o funcionamento do Node programando pequenos pacotes/módulos</h3><p>Se você é novo no Node.js, há muitos tutoriais aqui no freeCodeCamp e em outros lugares. Você pode conferir meu artigo <a href="https://codeburst.io/all-about-core-nodejs-part-1-b9f4b0a83278">All about Core Node.JS</a> (em inglês), por exemplo.</p><p>Sem mais delongas, vamos ao assunto em discussão: "Emissores de Eventos". Os emissores de eventos desempenham um papel muito importante no ecossistema do Node.js.</p><p>O EventEmitter (Emissor de Eventos) é um módulo que facilita a comunicação/interação entre objetos no Node. O EventEmitter está no centro da arquitetura orientada a eventos assíncrona do Node. Muitos dos módulos internos do Node são herdados do EventEmitter, incluindo <em>frameworks</em> proeminentes, como o Express.js.</p><p>O conceito é bastante simples: objetos emissores emitem eventos nomeados, que fazem com que ouvintes (em inglês, <em>listeners</em>) previamente registrados sejam chamados. Assim, um objeto emissor possui basicamente duas funcionalidades principais:</p><ul><li>Emitir eventos nomeados.</li><li>Registrar e cancelar o registro de funções do ouvinte.</li></ul><p>É meio como um padrão de desenho pub/sub ou observador (embora não exatamente).</p><h3 id="o-que-criaremos-neste-tutorial">O que criaremos neste tutorial</h3><ul><li>classe EventEmitter</li><li>método on/addEventListener</li><li>método off/removeEventListener</li><li>método once</li><li>método emit</li><li>método rawListeners</li><li>método listenerCount</li></ul><p>Os recursos básicos acima são suficientes para implementar um sistema completo usando o modelo de eventos.</p><p>Antes de entrarmos na programação, vamos dar uma olhada em como usaremos a classe EventEmitter. Observe que nosso código imitará a API exata do módulo "events" do Node.js.</p><p>Na verdade, se você substituir nosso EventEmitter pelo módulo "events" integrado do Node.js, você obterá o mesmo resultado.</p><h3 id="exemplo-1-crie-uma-inst-ncia-de-emissor-de-evento-e-registre-algumas-fun-es-de-retorno">Exemplo 1 - Crie uma instância de emissor de evento e registre algumas funções de retorno</h3><pre><code>const myEmitter = new EventEmitter();

function c1() {
   console.log('Ocorreu um evento!');
}

function c2() {
   console.log('E mais outro!');
}

myEmitter.on('eventOne', c1); // Registro para eventOne
myEmitter.on('eventOne', c2); // Registro para eventOne</code></pre><p>Quando o evento "eventOne" é emitido, ambas as funções de retorno acima devem ser invocadas.</p><pre><code>myEmitter.emit('eventOne');</code></pre><p>A saída no console será a seguinte:</p><pre><code>Ocorreu um evento!
E mais outro!</code></pre><h3 id="exemplo-2-registrando-para-o-evento-ser-disparado-apenas-uma-vez-usando-once">Exemplo 2 - Registrando para o evento ser disparado apenas uma vez usando "once"</h3><pre><code>myEmitter.once('eventOnce', () =&gt; console.log('eventOnce disparado apenas uma vez')); </code></pre><p>Emitindo o evento "eventOnce":</p><pre><code>myEmitter.emit('eventOne');</code></pre><p>A seguinte saída deve aparecer no console:</p><pre><code>eventOnce disparado apenas uma vez</code></pre><p>Emitir eventos registrados com "once" novamente não terá impacto.</p><pre><code>myEmitter.emit('eventOne');</code></pre><p>Uma vez que o evento foi emitido apenas uma vez, a instrução acima não terá impacto.</p><h3 id="exemplo-3-registrando-se-para-o-evento-com-par-metros-de-fun-o-de-retorno">Exemplo 3 - Registrando-se para o evento com parâmetros de função de retorno</h3><pre><code>myEmitter.on('status', (code, msg)=&gt; console.log(`Obtive ${code} e ${msg}`));</code></pre><p>Emitindo o evento com parâmetros:</p><pre><code>myEmitter.emit('status', 200, 'ok');</code></pre><p>A saída no console será a seguinte:</p><pre><code>Obtive 200 e ok</code></pre><p>OBSERVAÇÃO: Você pode emitir eventos várias vezes (exceto os registrados com o método "once").</p><h3 id="exemplo-4-cancelando-o-registro-de-eventos">Exemplo 4 - Cancelando o registro de eventos</h3><pre><code>myEmitter.off('eventOne', c1);</code></pre><p>Agora, se você emitir o evento da seguinte forma, nada acontecerá e será um "noop":</p><pre><code>myEmitter.emit('eventOne');  // noop</code></pre><h3 id="exemplo-5-obtendo-contagem-de-ouvintes">Exemplo 5 - Obtendo contagem de ouvintes</h3><pre><code>console.log(myEmitter.listenerCount('eventOne'));</code></pre><p>OBSERVAÇÃO: Se o registro do evento foi cancelado usando o método "off" ou "removeListener", a contagem será 0.</p><h3 id="exemplo-6-obtendo-ouvintes-brutos">Exemplo 6 - Obtendo ouvintes brutos</h3><pre><code>console.log(myEmitter.rawListeners('eventOne'));</code></pre><h3 id="exemplo-7-exemplo-de-demonstra-o-ass-ncrona">Exemplo 7 - Exemplo de demonstração assíncrona</h3><pre><code>// Exemplo 2-&gt;Adaptado de um texto de Sameer Buna. Grato!
class WithTime extends EventEmitter {
  execute(asyncFunc, ...args) {
    this.emit('begin');
    console.time('execute');
    this.on('data', (data)=&gt; console.log('got data ', data));
    asyncFunc(...args, (err, data) =&gt; {
      if (err) {
        return this.emit('error', err);
      }
      this.emit('data', data);
      console.timeEnd('execute');
      this.emit('end');
    });
  }
}</code></pre><p>Usando o emissor de evento "withTime":</p><pre><code>const withTime = new WithTime();

withTime.on('begin', () =&gt; console.log('Prestes a executar'));
withTime.on('end', () =&gt; console.log('Execução encerrada'));

const readFile = (url, cb) =&gt; {
  fetch(url)
    .then((resp) =&gt; resp.json()) // Transformar os dados em json
    .then(function(data) {
      cb(null, data);
    });
}

withTime.execute(readFile, 'https://jsonplaceholder.typicode.com/posts/1');</code></pre><p>Verifique a saída no console. A lista de postagens será exibida junto com outros logs.</p><h3 id="o-padr-o-observador-para-nosso-emissor-de-evento">O padrão Observador para nosso emissor de evento</h3><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/05/image-2.png" class="kg-image" alt="image-2" width="532" height="649" loading="lazy"></figure><h3 id="diagrama-visual-1-m-todos-em-nosso-eventemitter-">Diagrama visual 1 (métodos em nosso EventEmitter)</h3><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/05/image-4.png" class="kg-image" alt="image-4" width="484" height="494" loading="lazy"></figure><p>Como agora entendemos a utilização da API, vamos programar o módulo.</p><h3 id="o-c-digo-de-exemplo-completo-para-a-classe-eventemitter">O código de exemplo completo para a classe EventEmitter</h3><p>Estaremos preenchendo os detalhes de modo incremental nas próximas seções.</p><pre><code>class EventEmitter {
  listeners = {};  // par chave-valor
  
  addListener(eventName, fn) {}
  on(eventName, fn) {}
  
  removeListener(eventName, fn) {}
  off(eventName, fn) {}
  
  once(eventName, fn) {}
  
  emit(eventName, ...args) { }
  
  listenerCount(eventName) {}
  
  rawListeners(eventName) {}
}</code></pre><p>Começamos criando o modelo para a classe EventEmitter junto com um objeto para armazenar os ouvintes. Os ouvintes serão armazenados como um par chave-valor. O valor pode ser uma lista (já que para o mesmo evento permitimos que vários ouvintes sejam cadastrados).</p><h3 id="1-o-m-todo-addlistener-">1. O método addListener()</h3><p>Vamos agora implementar o método addListener. Ele recebe um nome de evento e uma função de retorno para ser executada.</p><pre><code>addListener(event, fn) {
    this.listeners[event] = this.listeners[event] || [];
    this.listeners[event].push(fn);
    return this;
  }</code></pre><h3 id="uma-pequena-explica-o-">Uma pequena explicação:</h3><p>O evento addListener verifica se o evento já está registrado. Se estiver, retorna o array. Caso contrário, o array estará vazio.</p><pre><code>this.listeners[event] // retornará o array de eventos ou undefined (registro inicial)</code></pre><p>Por exemplo…</p><p>Vamos entender isso com um exemplo de uso. Vamos criar um eventEmitter e registrar um "test-event". Esta é a primeira vez que o "test-event" está sendo registrado.</p><pre><code>const eventEmitter = new EventEmitter();
eventEmitter.addListener('test-event', 
 ()=&gt; { console.log ("test one") } 
);</code></pre><p>Dentro do método addListener():</p><pre><code>this.listeners[event] =&gt;  this.listeners['test-event'] 
                  =&gt; undefined || []
                  =&gt; []</code></pre><p>O resultado será:</p><pre><code>this.listeners['test-event'] = [];  // empty array</code></pre><p>Espero que isso torne o método "addListener" muito claro para decifrar e entender.</p><p><strong>Uma observação: várias funções de retornos podem ser registradas para o mesmo evento.</strong></p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/05/image-5.png" class="kg-image" alt="image-5" width="579" height="755" loading="lazy"></figure><h3 id="2-o-m-todo-on-">2. O método on()</h3><p>Este é apenas um apelido para o método "addListener". Usaremos o método "on" mais do que o método "addListener" por uma questão de conveniência.</p><pre><code>on(event, fn) {
  return this.addListener(event, fn);
}</code></pre><h3 id="3-o-m-todo-removelistener-event-fn-">3. O método <strong>removeListener(event, fn)</strong></h3><p>O método "removeListener" recebe um nome de evento e a função de retorno como parâmetros. Ele remove o ouvinte mencionado do array de eventos.</p><p>OBSERVAÇÃO: Se o evento tiver vários ouvintes, os outros ouvintes não serão afetados.</p><p>Primeiro, vamos dar uma olhada no código completo para "removeListener".</p><pre><code>removeListener (event, fn) {
    let lis = this.listeners[event];
    if (!lis) return this;
    for(let i = lis.length; i &gt; 0; i--) {
      if (lis[i] === fn) {
        lis.splice(i,1);
        break;
      }
    }
    return this;
}</code></pre><p>Aqui está o método "removeListener" explicado passo a passo:</p><ul><li>Obtém o array de ouvintes por evento.</li><li>Se nenhum for encontrado, retornar "this" para encadeamento.</li><li>Se encontrado, percorre todos os ouvintes. Se o ouvinte atual corresponde ao parâmetro "fn", usa o método "splice" do array para removê-lo. Depois, sai do laço.</li><li>Retorna "this" para continuar encadeando.</li></ul><h3 id="4-o-m-todo-off-event-fn-">4. O método off(event, fn)</h3><p>Este é apenas um apelido para o método "removeListener". Estaremos usando o método "off" mais do que o método "removeListener" por uma questão de conveniência.</p><pre><code>off(event, fn) {
    return this.removeListener(event, fn);
  }</code></pre><h3 id="5-o-m-todo-once-eventname-fn-">5. O método once(eventName, fn)</h3><p>Adiciona uma função de ouvinte única para o evento chamado "eventName". Na próxima vez que o nome do evento for acionado, esse ouvinte será removido e, em seguida, invocado.</p><p>Use para eventos do tipo configuração/inicialização.</p><p>Vamos dar uma olhada no código.</p><pre><code>once(eventName, fn) {
    this.listeners[event] = this.listeners[eventName] || [];
    const onceWrapper = () =&gt; {
      fn();
      this.off(eventName, onceWrapper);
    }
    this.listeners[eventName].push(onceWrapper);
    return this;
}</code></pre><p>Aqui está o método "once" explicado passo a passo:</p><ul><li>Obtém o objeto de array de eventos. Se for a primeira vez, o array estará vazio.</li><li>Cria uma função de invólucro chamada "onceWrapper", que invocará a função "fn" quando o evento for emitido e também removerá o ouvinte.</li><li>Adiciona a função de invólucro ao array.</li><li>Retorna "this" para encadeamento.</li></ul><h3 id="6-o-m-todo-emit-eventname-args-">6. O método emit(eventName, ..args)</h3><p>Chama de modo síncrono cada um dos ouvintes registrados para o evento com o nome "eventName", na ordem em que foram registrados, passando os argumentos fornecidos para cada um.</p><p>Retorna verdadeiro (true) se o evento tiver ouvintes ou falso (false), do contrário.</p><pre><code>emit(eventName, ...args) {
    let fns = this.listeners[eventName];
    if (!fns) return false;
    fns.forEach((f) =&gt; {
      f(...args);
    });
    return true;
}</code></pre><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/05/image-1-1.png" class="kg-image" alt="image-1-1" width="553" height="761" loading="lazy"></figure><p>Aqui está o método "emit" explicado passo a passo:</p><ul><li>Obtém as funções registradas para o parâmetro nome do evento.</li><li>Se não houver ouvintes, retorna <code>false</code>.</li><li>Para todos os ouvintes de função, invoca a função com os argumentos fornecidos.</li><li>Retorna <code>true</code> quando termina.</li></ul><h3 id="7-o-m-todo-listenercount-eventname-">7. O método listenerCount(eventName)</h3><p>Retorna o número de ouvintes escutando o evento com o nome "eventName".</p><p>Aqui está o código-fonte:</p><pre><code>listenerCount(eventName) {
    let fns = this.listeners[eventName] || [];
    return fns.length;
}</code></pre><p>Aqui está o método "listenerCount" explicado passo a passo:</p><ol><li>Obtém as funções/ouvintes consideradas ou um array vazio se não houver nenhum.</li><li>Retorna o comprimento (desse array).</li></ol><h3 id="8-o-m-todo-rawlisteners-eventname-">8. O método rawListeners(eventName)</h3><p>Retorna uma cópia do array de ouvintes para o evento com o nome "eventName", incluindo quaisquer invólucros (como os criados por .once()). Os invólucros de .once() nesta implementação não estarão disponíveis se o evento tiver sido emitido uma vez.</p><pre><code>rawListeners(event) {
    return this.listeners[event];
}</code></pre><p>O código-fonte completo, para referência:</p><pre><code>class EventEmitter {
  listeners = {}
  
  addListener(eventName, fn) {
    this.listeners[eventName] = this.listeners[eventName] || [];
    this.listeners[eventName].push(fn);
    return this;
  }

  on(eventName, fn) {
    return this.addListener(eventName, fn);
  }

  once(eventName, fn) {
    this.listeners[eventName] = this.listeners[eventName] || [];
    const onceWrapper = () =&gt; {
      fn();
      this.off(eventName, onceWrapper);
    }
    this.listeners[eventName].push(onceWrapper);
    return this;
  }

  off(eventName, fn) {
    return this.removeListener(eventName, fn);
  }

  removeListener (eventName, fn) {
    let lis = this.listeners[eventName];
    if (!lis) return this;
    for(let i = lis.length; i &gt; 0; i--) {
      if (lis[i] === fn) {
        lis.splice(i,1);
        break;
      }
    }
    return this;
  }

  emit(eventName, ...args) {
    let fns = this.listeners[eventName];
    if (!fns) return false;
    fns.forEach((f) =&gt; {
      f(...args);
    });
    return true;
  }

  listenerCount(eventName) {
    let fns = this.listeners[eventName] || [];
    return fns.length;
  }

  rawListeners(eventName) {
    return this.listeners[eventName];
  }
}</code></pre><p>O código completo está disponível <a href="https://jsbin.com/gibofab/edit?js,console,output">aqui</a>.</p><p>Como exercício, sinta-se à vontade para implementar outras APIs de eventos da <a href="https://nodejs.org/api/events.html">documentação</a> (em inglês).</p><p>Se você gostou deste artigo e deseja ver mais artigos semelhantes, sinta-se à vontade para compartilhá-lo. :)</p><p>OBSERVAÇÃO: O código foi otimizado para legibilidade e não para desempenho. Talvez, como exercício, você possa otimizar o código e compartilhá-lo. Não testei completamente para casos extremos e algumas validações podem estar imprecisas, pois foi um rascunho rápido.</p><p>Este artigo faz parte de um curso em vídeo que criariei, chamado "Node.JS Master Class — Build Your Own ExpressJS-Like MVC Framework from scratch".</p><p>O título do curso, porém, ainda não é definitivo.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como configurar o login do Google no React Native com Firebase ]]>
                </title>
                <description>
                    <![CDATA[ O login do Google é um ótimo recurso de login a ser oferecido aos usuários de sua aplicação. Ele facilita para os usuários a criação de uma conta e o login. Melhor do que isso, o Firebase torna extremamente fácil para os desenvolvedores adicionar suporte ao login do Google. Configurar ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-configurar-o-login-do-google-no-react-native-com-firebase/</link>
                <guid isPermaLink="false">63234337926c2f06e57cf4cf</guid>
                
                    <category>
                        <![CDATA[ React Native ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Renato Almeida ]]>
                </dc:creator>
                <pubDate>Mon, 05 Dec 2022 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2022/11/React-native-Google-login.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/google-login-with-react-native-and-firebase/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Set Up Google Login in React Native &amp; Firebase</a>
      </p><p>O login do Google é um ótimo recurso de login a ser oferecido aos usuários de sua aplicação. Ele facilita para os usuários a criação de uma conta e o login.</p><p>Melhor do que isso, o Firebase torna extremamente fácil para os desenvolvedores adicionar suporte ao login do Google. Configurar o ambiente do React Native, no entanto, pode criar alguns desafios, os quais são totalmente tratados neste tutorial.</p><p>O React Native e o SDK do Firebase tornam a implementação do login do Google bastante simples. Vamos construir uma aplicação simples que tem apenas um único botão de login do Google. Uma vez que o usuário faça login no Google com sucesso, exibiremos as informações do usuário recuperadas de sua conta do Google, bem como um botão de logout.</p><p>Você também pode adicionar o login do Facebook à aplicação se estiver interessado em fornecer ainda mais opções de login para seus usuários. Você pode conferir este guia para <a href="https://www.instamobile.io/react-native-tutorials/facebook-login-react-native-firebase/">login do Facebook no React Native com Firebase</a> (texto em inglês) se quiser aprender mais sobre como configurar o login no Facebook.</p><h2 id="por-que-usar-um-bot-o-de-login-do-google-em-aplica-es-para-dispositivos-m-veis"><strong>Por que usar um botão de login do Google em aplicações para dispositivos móveis<strong>?</strong></strong></h2><ol><li>Usar o Google ou outras aplicações de terceiros pode fazer o seu processo de autenticação descomplicado e amigável. Os usuários não precisam perder tempo no processo de registro, o que melhorará tremendamente suas taxas de registro e retenção.</li><li>É seguro e protegido.</li><li>Os usuários confiam mais no Google ou no Facebook do que em um portal ou aplicação desconhecida da internet.</li><li>Ele fornece uma boa experiência ao usuário. Como usuário, temos pouca paciência para qualquer ação ou trabalho que precisemos fazer, especialmente em uma aplicação bastante desconhecida que estamos testando pela primeira vez.</li></ol><p>Sem mais delongas, vamos pular diretamente para a parte de desenvolvimento de aplicações deste tutorial.</p><h2 id="configurando-o-projeto-do-firebase"><strong>Configurando o projeto do Firebase</strong></h2><p>Vá até o <a href="https://firebase.google.com/" rel="noopener">console do Firebase</a> e crie um projeto do Firebase:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/11/create-new-firebase-project.png" class="kg-image" alt="create-new-firebase-project" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/11/create-new-firebase-project.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/11/create-new-firebase-project.png 807w" sizes="(min-width: 720px) 720px" width="807" height="450" loading="lazy"><figcaption>Cria um projeto do Firebase</figcaption></figure><p>Aqui, precisaremos configurar o nome do projeto do Firebase e o identificador da aplicação. Então, vamos primeiro criar a aplicação do React Native.</p><h2 id="criando-o-projeto-do-react-native"><strong>Criando o projeto do <strong>React Native</strong></strong></h2><p>Primeiro, precisamos criar um projeto do React Native usando o seguinte comando:</p><p><code>react-native init instamobile-google-login-demo</code></p><p>Aqui, demos ao projeto o nome <strong>instamobile-google-login-demo</strong>. Agora, precisamos instalar o pacote <strong>react-native-google-signin</strong> usando o seguinte comando:</p><p><code>yarn add react-native-google-singin</code></p><p>O pacote <code>react-native-google-signin</code> é usado para implementar as funções de autenticação do Google na aplicação do React Native. Agora, precisamos importar os módulos e componentes necessários do respectivo pacote, conforme mostrado no trecho de código abaixo:</p><figure class="kg-card kg-code-card"><pre><code class="language-javascript">import {
GoogleSignin,
GoogleSigninButton,
statusCodes,
} from 'react-native-google-signin';</code></pre><figcaption>Importa o componente de login do google</figcaption></figure><p>Em seguida, precisamos criar os estados para lidar com o estado de autenticação e as informações do usuário. Para isso, utilizamos o módulo <code>useState</code>, conforme mostrado no trecho de código abaixo:</p><figure class="kg-card kg-code-card"><pre><code class="language-javascript">const [loggedIn, setloggedIn] = useState(false);
const [userInfo, setuserInfo] = useState([]);</code></pre><figcaption>Adiciona os estados</figcaption></figure><p>Agora, precisamos criar uma função de login para lidar com a autenticação, conforme mostrado no trecho de código abaixo:</p><figure class="kg-card kg-code-card"><pre><code class="language-javascript">_signIn = async () =&gt; {
  try {
    await GoogleSignin.hasPlayServices();
    const {accessToken, idToken} = await GoogleSignin.signIn();
    setloggedIn(true);
  } catch (error) {
    if (error.code === statusCodes.SIGN_IN_CANCELLED) {
      // usuário cancelou o fluxo de login
      alert('Cancel');
    } else if (error.code === statusCodes.IN_PROGRESS) {
      alert('Signin in progress');
      // operação (por exemplo, o login) já está em andamento
    } else if (error.code === statusCodes.PLAY_SERVICES_NOT_AVAILABLE) {
      alert('PLAY_SERVICES_NOT_AVAILABLE');
      // serviços de execução não disponível ou desatualizado
    } else {
      // algum outro erro ocorreu
    }
  }
};</code></pre><figcaption>Adiciona a função do google sign-in</figcaption></figure><p>A seguir, precisamos inicializar a configuração do objeto de login do Google, fazendo uso da função <code>useEffect</code>:</p><pre><code class="language-javascript">useEffect(() =&gt; {
   GoogleSignin.configure({
     scopes: ['email'], // qual API você quer acessar em nome do usuário; o padrão é o email e o perfil
     webClientId:
       '418977770929-g9ou7r9eva1u78a3anassxxxxxxx.apps.googleusercontent.com', // o ID do client do tipo WEB para seu servidor (necessário para verificar o ID do usuário e o acesso off-line)
     offlineAccess: true, // se você deseja acessar a API do Google API em nome do usuário DE SEU SERVIDOR
   });
 }, []);</code></pre><p>Por fim, precisamos de uma função que lide com a ação de logout. Para isso, vamos implementar o método <code>signOut</code>, conforme mostrado no trecho de código abaixo:</p><figure class="kg-card kg-code-card"><pre><code class="language-javascript">signOut = async () =&gt; {
    try {
      await GoogleSignin.revokeAccess();
      await GoogleSignin.signOut();
      setloggedIn(false);
      setuserInfo([]);
    } catch (error) {
      console.error(error);
    }
  };</code></pre><figcaption>Adiciona a função de sign-out do Google&nbsp;</figcaption></figure><p>Agora, precisamos apresentar os componentes na tela também. Para isso, vamos fazer uso de vários componentes como <code>View</code> e <code>Button</code>:</p><figure class="kg-card kg-code-card"><pre><code class="language-javascript">return (
    &lt;&gt;
      &lt;StatusBar barStyle="dark-content" /&gt;
      &lt;SafeAreaView&gt;
        &lt;ScrollView
          contentInsetAdjustmentBehavior="automatic"
          style={styles.scrollView}&gt;
          &lt;Header /&gt;

          &lt;View style={styles.body}&gt;
            &lt;View style={styles.sectionContainer}&gt;
              &lt;GoogleSigninButton
                style={{width: 192, height: 48}}
                size={GoogleSigninButton.Size.Wide}
                color={GoogleSigninButton.Color.Dark}
                onPress={this._signIn}
              /&gt;
            &lt;/View&gt;
            &lt;View style={styles.buttonContainer}&gt;
              {!loggedIn &amp;&amp; &lt;Text&gt;You are currently logged out&lt;/Text&gt;}
              {loggedIn &amp;&amp; (
                &lt;Button
                  onPress={this.signOut}
                  title="LogOut"
                  color="red"&gt;&lt;/Button&gt;
              )}
            &lt;/View&gt;
          &lt;/View&gt;
        &lt;/ScrollView&gt;
      &lt;/SafeAreaView&gt;
    &lt;/&gt;
  );</code></pre><figcaption>Código da IU</figcaption></figure><p>Agora, se nós executarmos nosso projeto no emulador, teremos os seguintes resultados:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/11/google-login-first-screen.png" class="kg-image" alt="google-login-first-screen" width="560" height="315" loading="lazy"><figcaption>Login com Google React Native</figcaption></figure><p>Bem legal, certo? Concluímos a implementação (tanto da interface do usuário quanto da lógica de negócios) a nível do React Native em nosso projeto.</p><p>Como você pode ver, temos um botão "Sign in with Google" (<em>Fazer login com o Google</em>, em português) que se converte em um botão de logout assim que a operação de login é concluída com sucesso.</p><p>Agora, vamos configurar o pacote do Google SignIn e a aplicação do Firebase.</p><h2 id="configurando-os-projetos-nativos-do-ios-e-do-android"><strong><strong>Configur</strong>ando os projetos nativos do <strong>iOS </strong>e do<strong> Android</strong></strong></h2><p>Existem algumas etapas de configuração que precisamos seguir antes que o projeto esteja totalmente funcionando. Elas estão relacionadas principalmente ao verdadeiro lado nativo da aplicação.</p><h3 id="para-ios"><strong>Para<strong> iOS</strong></strong></h3><p>No VSCode (ou em qualquer Terminal), basta executar <code>cd ios &amp;&amp; pod install</code>. Em seguida, abra o arquivo <em>.xcworkspace</em> no Xcode (da pasta ios) e verifique se os Pods estão incluídos:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/11/install-google-login-lib-in-xcode.png" class="kg-image" alt="install-google-login-lib-in-xcode" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/11/install-google-login-lib-in-xcode.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/11/install-google-login-lib-in-xcode.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2022/11/install-google-login-lib-in-xcode.png 1019w" sizes="(min-width: 720px) 720px" width="1019" height="523" loading="lazy"><figcaption>Instala a biblioteca google login no xcode</figcaption></figure><h3 id="para-android"><strong>Para<strong> Android</strong></strong></h3><p>1. Primeiro, precisamos vincular o módulo nativo.</p><ul><li>Se RN &gt;= 0.60, você não precisa fazer nada, graças à vinculação automática.</li><li>Se RN &lt; 0.60, execute <code>react-native link <strong><strong>react-native-google-signin</strong></strong></code>.</li></ul><p>2. Atualize o <strong><strong>android/build.gradle</strong></strong> com a seguinte configuração:</p><pre><code class="language-java">buildscript {
    ext {
        buildToolsVersion = "27.0.3"
        minSdkVersion = 16
        compileSdkVersion = 27
        targetSdkVersion = 26
        supportLibVersion = "27.1.1"
        googlePlayServicesAuthVersion = "16.0.1" // &lt;--- use esta versão ou uma mais recente
    }
...
    dependencies {
        classpath 'com.android.tools.build:gradle:3.1.2' // &lt;--- use esta versão ou uma mais recente
        classpath 'com.google.gms:google-services:4.1.0' // &lt;--- use esta versão ou uma mais recente
    }
...
allprojects {
    repositories {
        mavenLocal()
        google() // &lt;--- certifique-se de que isto está incluído
        jcenter()
        maven {
            // Todo o React Native (JS, fontes do Obj-C, binários do Android) é instalado a partir do npm
            url "$rootDir/../node_modules/react-native/android"
        }
    }
}</code></pre><p>3. Atualize o <code>android/app/build.gradle</code> com a seguinte configuração:</p><pre><code class="language-java">...
dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation "com.android.support:appcompat-v7:23.0.1"
    implementation "com.facebook.react:react-native:+"
    implementation(project(":react-native-community_google-signin")) // &lt;--- adicione esta dependência
}</code></pre><p>Confira se o <code>react-native link</code> vinculou o módulo nativo – porém, apenas se você usou o <code>react-native link</code>!</p><p>Em <code>android/settings.gradle</code>, devemos ter as seguintes configurações:</p><figure class="kg-card kg-code-card"><pre><code class="language-java">...
include ':react-native-google-signin', ':app'
project(':react-native-google-signin').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/google-signin/android')</code></pre><figcaption>Configura o google login para android em setting.gradle</figcaption></figure><p>Em seguida, em <code>MainApplication.java</code> , devemos ter o pacote do Google adicionado, conforme o trecho de código a seguir:</p><figure class="kg-card kg-code-card"><pre><code class="language-java">import co.apptailor.googlesignin.RNGoogleSigninPackage;  // &lt;--- importar

public class MainApplication extends Application implements ReactApplication {

  ......

  @Override
    protected List&lt;ReactPackage&gt; getPackages() {
      return Arrays.&lt;ReactPackage&gt;asList(
          new MainReactPackage(),
          new RNGoogleSigninPackage() // &lt;-- isto precisa estar na lista
      );
    }
  ......

}</code></pre><figcaption>Configura o google login para android em MainApplication.java</figcaption></figure><h2 id="configurando-o-firebase"><strong>Configurando o <strong>Firebase</strong></strong></h2><h3 id="para-ios-1"><strong>Para<strong> iOS</strong></strong></h3><p>Agora, precisamos começar a configuração do Firebase. No Firebase, precisamos configurar uma aplicação em nuvem do Google. Quando configuramos o método de autenticação no Firebase, no entanto, isso também cria uma aplicação em nuvem do Google.</p><p>Primeiro, precisamos criar a aplicação do iOS do Firebase para obter o <strong>GoogleServiceinfo.plist</strong>, como mostrado na captura de tela abaixo:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/11/add-new-firebase-app-name.png" class="kg-image" alt="add-new-firebase-app-name" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/11/add-new-firebase-app-name.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/11/add-new-firebase-app-name.png 713w" width="713" height="525" loading="lazy"><figcaption>Adiciona novo nome de aplicação do Firebase</figcaption></figure><p>Em seguida, copiamos o arquivo <strong><strong>GoogleService-info.plist</strong></strong> para o projeto do Xcode, como mostrado na captura de tela abaixo:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/11/add-google-service-plist-to-xcode.png" class="kg-image" alt="add-google-service-plist-to-xcode" width="263" height="377" loading="lazy"><figcaption>Adiciona o serviço do google plist ao xcode</figcaption></figure><p>Agora, precisamos adicionar o ID do client invertido que está presente no arquivo <strong>GoogleService-info.plist</strong> aos tipos de URL, tal como mostrado na captura de tela abaixo:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/11/get-reverse-client-id-from-xcode.png" class="kg-image" alt="get-reverse-client-id-from-xcode" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/11/get-reverse-client-id-from-xcode.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/11/get-reverse-client-id-from-xcode.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2022/11/get-reverse-client-id-from-xcode.png 1020w" sizes="(min-width: 720px) 720px" width="1020" height="395" loading="lazy"><figcaption>Obtém o id do client invertido do xcode</figcaption></figure><p>O próximo passo é ir até <strong><strong>Info</strong></strong> → <strong><strong>URL Types</strong></strong> e preencher o <strong><strong>URL Schemes</strong></strong> como mostrado na captura de tela abaixo:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/11/add-url-scheme-to-xcode.png" class="kg-image" alt="add-url-scheme-to-xcode" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/11/add-url-scheme-to-xcode.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/11/add-url-scheme-to-xcode.png 999w" sizes="(min-width: 720px) 720px" width="999" height="628" loading="lazy"><figcaption>Adiciona o url scheme ao xcode</figcaption></figure><h3 id="para-android-1"><strong>Para<strong> Android</strong></strong></h3><p>Primeiro, precisamos criar uma aplicação do Android no Firebase. Para isso, precisamos de um nome de pacote e certificado <strong>SHA-1</strong> da nossa aplicação. Em seguida, podemos registrar a aplicação do Firebase, conforme mostrado abaixo:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/11/create-new-android-firebase-app-300x252.png" class="kg-image" alt="create-new-android-firebase-app-300x252" width="300" height="252" loading="lazy"><figcaption>Cria uma nova aplicação do Android do Firebase</figcaption></figure><p>Podemos obter o nome do pacote em <strong>MainApplication.java</strong> do nosso projeto, conforme destacado no trecho de código abaixo:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/11/find-out-bundle-name-in-android-app-1024x408.png" class="kg-image" alt="find-out-bundle-name-in-android-app-1024x408" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/11/find-out-bundle-name-in-android-app-1024x408.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/11/find-out-bundle-name-in-android-app-1024x408.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2022/11/find-out-bundle-name-in-android-app-1024x408.png 1024w" sizes="(min-width: 720px) 720px" width="1024" height="408" loading="lazy"><figcaption>Descobre o nome do pacote na aplicação do Android</figcaption></figure><p>Em seguida, podemos obter a chave SHA-1 no arquivo Keystore. No diretório <strong>android/app</strong>, podemos executar o comando:</p><figure class="kg-card kg-code-card"><pre><code class="language-shell">cd android/app ; 
keytool -exportcert -keystore debug.keystore -list -v</code></pre><figcaption>Gera sha-1</figcaption></figure><p>Então, a chave <strong>SHA-1</strong> aparecerá, conforme mostrado na captura de tela abaixo:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/11/generate-sha1-for-register-android-app-in-firebase.png" class="kg-image" alt="generate-sha1-for-register-android-app-in-firebase" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/11/generate-sha1-for-register-android-app-in-firebase.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/11/generate-sha1-for-register-android-app-in-firebase.png 814w" sizes="(min-width: 720px) 720px" width="814" height="278" loading="lazy"><figcaption>Gera sha1 para registrar a aplicação do Android no Firebase</figcaption></figure><p>Após criar a aplicação de configuração do Firebase com sucesso, precisamos baixar o arquivo <strong>google-services.json</strong> e copiá-lo para o diretório, conforme mostrado na captura de tela abaixo:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/11/add-google-service-json-to-android-app-folder-250x300.png" class="kg-image" alt="add-google-service-json-to-android-app-folder-250x300" width="250" height="300" loading="lazy"><figcaption>Adiciona google service json à pasta da aplicação do android</figcaption></figure><p>Agora, a etapa final é configurar um componente de login do Google no Android.</p><h3 id="instalando-o-pacote-do-firebase-do-react-native"><strong><strong>Instal</strong>ando o pacote do <strong>Firebase</strong> do <strong>React Native </strong></strong></h3><p>Para instalar o pacote <strong>react-native-firebase</strong>, versão 6, precisamos executar o seguinte comando no prompt de comando do nosso projeto:</p><figure class="kg-card kg-code-card"><pre><code class="language-shell"># Using npm 
npm install --save @react-native-firebase/app 
# Using Yarn 
yarn add @react-native-firebase/app</code></pre><figcaption>Instala o componente principal react-native-firebase</figcaption></figure><p>O módulo <code>@react-native-firebase/app</code> deve ser instalado antes de usar qualquer outro serviço do Firebase.</p><h3 id="para-ios-2"><strong>Para<strong> iOS</strong></strong></h3><p>Já adicionamos <strong>GoogleService-Info.plist</strong> ao Xcode. O que resta é permitir que o Firebase no iOS use as credenciais. O SDK do Firebase para iOS deve ser configurado durante a fase de inicialização da aplicação.</p><p>Para fazer isso, precisamos abrir nosso arquivo <code>/ios/{projectName}/AppDelegate.m</code>, e adicionar o seguinte:</p><p>Na parte superior do arquivo, precisamos importar o SDK do Firebase:</p><figure class="kg-card kg-code-card"><pre><code class="language-swift">#import &lt;Firebase.h&gt;</code></pre><figcaption>Inclui o Firebase</figcaption></figure><p>Dentro do método <code>didFinishLaunchingWithOptions</code> existente, precisamos adicionar o seguinte ao topo do método:</p><figure class="kg-card kg-code-card"><pre><code class="language-m">- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  // Adicione-me --- \/
  if ([FIRApp defaultApp] == nil) {
    [FIRApp configure];
  }
  // Adicione-me --- /\
  // ...
}</code></pre><figcaption>Firebase React Native</figcaption></figure><p>Por fim, precisamos executar o seguinte comando para finalizar a instalação do pacote CocoaPods:</p><figure class="kg-card kg-code-card"><pre><code class="language-shell">cd ios ; pod install</code></pre><figcaption>instala CocoaPods</figcaption></figure><p>É isso. Concluímos a instalação do pacote principal do Firebase no iOS.</p><h3 id="para-android-2"><strong>Para<strong> Android</strong></strong></h3><p>Precisamos configurar o Firebase com as credenciais do Android. Para permitir que o Firebase no Android use as credenciais, o <em>plugin</em> google-services deve estar ativado no projeto. Isso requer a modificação em dois arquivos no diretório Android.</p><p>Primeiro, adicione o plug-in google-services como uma dependência dentro do arquivo <strong>android/build.gradle</strong>:</p><figure class="kg-card kg-code-card"><pre><code class="language-java">buildscript {
  dependencies {
    // ... outras dependências
    classpath 'com.google.gms:google-services:4.2.0'
    // Adicione-me --- /\
  }
}
// Por fim, execute o plug-in adicionando o seguinte ao final do arquivo /android/app/build.gradle:

apply plugin: 'com.google.gms.google-services'</code></pre><figcaption>Adiciona o serviço google</figcaption></figure><h2 id="m-dulo-de-autentica-o-do-react-native-firebase"><strong>Módulo de autenticação do <strong>React Native Firebase</strong></strong></h2><p>Após a conclusão da instalação, precisamos configurar o pacote pai do Firebase. Em seguida, precisamos instalar o módulo filho para autenticação. Para isso, precisamos abrir um terminal e executar o seguinte comando:</p><figure class="kg-card kg-code-card"><pre><code class="language-shell">yarn add @react-native-firebase/auth</code></pre><figcaption>install react native firebase auth&nbsp;</figcaption></figure><h3 id="para-ios-3"><strong>Para<strong> iOS</strong></strong></h3><p>Precisamos instalar os pods novamente na linha de comando:</p><figure class="kg-card kg-code-card"><pre><code>cd ios/ &amp;&amp; pod install</code></pre><figcaption>Instala o cacao pod</figcaption></figure><h3 id="para-android-3"><strong>Para<strong> Android</strong></strong></h3><p>Você pode seguir as instruções na <a href="https://rnfirebase.io/auth/usage/installation/android" rel="noopener">documentação oficial</a>, a qual é necessária somente se você estiver usando o React Native &lt;= 0.59 ou se precisar integrar manualmente a biblioteca.</p><h3 id="ativando-o-login-do-google-no-firebase"><strong>Ativando o login do <strong>Google </strong>no<strong> Firebase</strong></strong></h3><p>Precisamos ir ao console do Firebase. Em seguida, na seção Authentication (<em>Autenticação</em>, em português), precisamos clicar em Google, conforme mostrado na captura de tela abaixo:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/11/authentication-method-in-firebase-1024x396.png" class="kg-image" alt="authentication-method-in-firebase-1024x396" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/11/authentication-method-in-firebase-1024x396.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/11/authentication-method-in-firebase-1024x396.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2022/11/authentication-method-in-firebase-1024x396.png 1024w" sizes="(min-width: 720px) 720px" width="1024" height="396" loading="lazy"><figcaption>Método de autenticação no Firebase</figcaption></figure><p>Em seguida, precisamos habilitar a configuração e salvá-la conforme mostrado na captura de tela abaixo:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/11/select-support-email-in-firebase-app.png" class="kg-image" alt="select-support-email-in-firebase-app" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/11/select-support-email-in-firebase-app.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/11/select-support-email-in-firebase-app.png 928w" sizes="(min-width: 720px) 720px" width="928" height="472" loading="lazy"><figcaption>Ativa o e-mail de suporte do projeto</figcaption></figure><p>No <strong><strong>App.js</strong></strong>, precisamos importar o <strong><strong>auth</strong></strong> do pacote Firebase, como mostrado no trecho de código abaixo:</p><figure class="kg-card kg-code-card"><pre><code>import auth from '@react-native-firebase/auth';</code></pre><figcaption>Importa o auth do pacote firebase</figcaption></figure><p>Em seguida, precisamos integrar a configuração de autenticação à função de login. Após um login bem-sucedido, armazenamos o <strong>accessToken</strong> e o <strong>idToken</strong> no <strong>Firebase</strong>. Agora, podemos tentar fazer login com o Google em nossa aplicação do React Native de demonstração.</p><figure class="kg-card kg-code-card"><pre><code class="language-javacript">_signIn = async () =&gt; {
    try {
      await GoogleSignin.hasPlayServices();
      const {accessToken, idToken} = await GoogleSignin.signIn();
      setloggedIn(true);
      const credential = auth.GoogleAuthProvider.credential(
        idToken,
        accessToken,
      );
      await auth().signInWithCredential(credential);
    } catch (error) {</code></pre><figcaption>Função de Login do Firebase</figcaption></figure><p>Agora, concluímos com sucesso a integração do Login do Google em nossa aplicação do React Native:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/11/2020-06-29-17.52.16.gif" class="kg-image" alt="2020-06-29-17.52.16" width="330" height="701" loading="lazy"><figcaption>Resultado do login do Google com o React Native</figcaption></figure><p>Podemos ver novos dados que são adicionados ao console do Firebase:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/11/firebase-authentication-console.png" class="kg-image" alt="firebase-authentication-console" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/11/firebase-authentication-console.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/11/firebase-authentication-console.png 800w" sizes="(min-width: 720px) 720px" width="800" height="137" loading="lazy"><figcaption>Console de autenticação do firebase</figcaption></figure><h2 id="rastreando-o-status-do-usu-rio"><strong>Rastreando o status do usuário</strong></h2><p>Para verificar o status do login do usuário, usamos o Firebase Auth. Para isso, precisamos adicionar o método <strong>onAuthStateChanged</strong> ao <strong>useEffect</strong> para que ele seja executado em cada chamada do evento <strong>componentDidMount</strong>.</p><p>Além disso, precisamos passar um retorno de chamada para a função denominada <strong>onAuthStateChanged</strong> como um argumento, conforme mostrado no trecho de código abaixo:</p><figure class="kg-card kg-code-card"><pre><code class="language-javascript">useEffect(() =&gt; {
    .............
    const subscriber = auth().onAuthStateChanged(onAuthStateChanged);
    return subscriber; // remover a inscrição ao desmontar
  }, []);</code></pre><figcaption>Subscreve ao estado da autenticação</figcaption></figure><p>Na função <strong><strong>onAuthStateChanged, </strong></strong>tratamos os dados do estado local conforme mostrado no trecho de código abaixo:</p><figure class="kg-card kg-code-card"><pre><code class="language-javascript">function onAuthStateChanged(user) {
    setUser(user);
    console.log(user);
    if (user) setloggedIn(true);
  }</code></pre><figcaption>Define dados do usuário</figcaption></figure><p>Agora, precisamos armazenar os dados do usuário no estado. Em seguida, tentar exibir os dados do usuário após um login bem-sucedido. Para isso, precisamos usar o seguinte pedaço de código:</p><figure class="kg-card kg-code-card"><pre><code class="language-javascript">{!user &amp;&amp; &lt;Text&gt;You are currently logged out&lt;/Text&gt;}
{user &amp;&amp; (
  &lt;View&gt;
    &lt;Text&gt;Welcome {user.displayName}&lt;/Text&gt;
    &lt;Button
      onPress={this.signOut}
      title="LogOut"
      color="red"&gt;&lt;/Button&gt;
  &lt;/View&gt;
)}</code></pre><figcaption>Código para exibir as informações do usuário</figcaption></figure><p>Teremos o seguinte resultado em nosso simulador:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/11/show-auth-user-name.png" class="kg-image" alt="show-auth-user-name" width="442" height="813" loading="lazy"><figcaption>Logout do auth do Firebase</figcaption></figure><h2 id="logout-do-firebase"><strong>Logout do <strong>Firebase</strong></strong></h2><p>Para sair, precisamos remover todas as credenciais do usuário e revogar o token de login do Google.</p><p>Primeiro, precisamos aguardar o módulo <strong>GoogleSignin</strong> revogar o acesso e sair. Em seguida, chamamos o método <strong>signOut</strong> da autenticação do <strong>Firebase</strong> para fazer logout com êxito.</p><p>A implementação completa do código é fornecida no trecho de código abaixo:</p><figure class="kg-card kg-code-card"><pre><code class="language-javascript">signOut = async () =&gt; {
    try {
      await GoogleSignin.revokeAccess();
      await GoogleSignin.signOut();
      auth()
        .signOut()
        .then(() =&gt; alert('Your are signed out!'));
      setloggedIn(false);
      // setuserInfo([]);
    } catch (error) {
      console.error(error);
    }
  };</code></pre><figcaption>Função de logout do Firebase</figcaption></figure><p>Como resultado, agora podemos realizar operações de logout, conforme mostrado no trecho de código abaixo:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/11/firebase-signout-result.gif" class="kg-image" alt="firebase-signout-result" width="326" height="616" loading="lazy"><figcaption>Logout do Firebase com React Native</figcaption></figure><h2 id="conclus-o"><strong><strong>Conclus</strong>ão</strong></h2><p>Neste tutorial, aprendemos como configurar o Login do Google, além de armazenar um token de acesso, aproveitando o Firebase em nosso projeto React Native.</p><p>Primeiro, criamos o projeto do React Native com todos os componentes e configurações de funções necessários. Em seguida, aprendemos como configurar o Google Sign In e o Firebase para as plataformas do Android e do iOS. Por fim, configuramos o Firebase na aplicação do React Native usando um pacote do Firebase e exibimos os dados do usuário junto com o botão de logout.</p><p>Você pode baixar o código-fonte completo deste tutorial no <a href="https://github.com/florion101/firebase-google-login-react-native">Github</a>.</p><p>A melhor parte é que o Firebase e o Google Auth são compatíveis com todas as linguagens de desenvolvimento para dispositivos móveis, tais como <a href="https://www.instaflutter.com/">Flutter</a>, <a href="https://www.iosapptemplates.com/">Swift</a> ou <a href="https://www.instakotlin.com/">Kotlin</a>. As etapas de configuração e a abordagem arquitetural são exatamente as mesmas.</p><h2 id="pr-ximos-passos"><strong>Próximos passos</strong></h2><p>Agora que você aprendeu sobre como configurar o Login do Google com Firebase em aplicações do React Native, aqui estão alguns outros tópicos nos quais você pode dar uma olhada:</p><ul><li><a href="https://www.freecodecamp.org/portuguese/news/como-criar-uma-aplicacao-em-react-native-app-and-integrate-e-integra-la-com-firebase/">Como criar uma aplicação em React Native e integrá-la com Firebase</a></li><li>Firebase e React Native — &nbsp;<a href="https://www.instamobile.io/react-native-tutorials/push-notifications-react-native-firebase/" rel="noopener nofollow">Notificações push</a> | <a href="https://www.instamobile.io/mobile-development/react-native-firebase-storage/" rel="noopener nofollow">Armazenamento do Firebase</a> (textos em inglês)</li><li>Mais métodos de autenticação em React Native e Firebase — <a href="https://www.instamobile.io/mobile-development/google-login-react-native-firebase/" rel="noopener nofollow">Login do Google</a> | <a href="https://www.instamobile.io/react-native-tutorials/facebook-login-react-native-firebase/">Login do Facebook</a> | <a href="https://www.instamobile.io/mobile-development/firebase-phone-authentication-react-native/" rel="noopener nofollow">Autenticação OTP/SMS por telefone</a> (textos em inglês)</li></ul><p>Se você gostou deste tutorial do React Native, dê uma estrela no <a href="https://github.com/florion101/firebase-google-login-react-native">repositório do Github</a> e compartilhe-o com sua comunidade. Você pode conferir ainda mais <a href="https://www.instamobile.io/mobile-templates/react-native-templates-free/" rel="noopener">projetos do React Native gratuitos</a> na Instamobile. Obrigado!</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como formatar automaticamente seu código em Python com o Black ]]>
                </title>
                <description>
                    <![CDATA[ Escrever código em Python é uma coisa. Escrever o código em um formato bom é outra. Programadores júniores frequentemente focam em ter a certeza de que seus códigos estão funcionando e se esquecem de formatar o código corretamente ao longo do caminho. Se você escreve um programa pequeno (com mil ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-formatar-automaticamente-seu-codigo-em-python-com-o-black/</link>
                <guid isPermaLink="false">6321717e926c2f06e57cedcd</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Renato Almeida ]]>
                </dc:creator>
                <pubDate>Thu, 06 Oct 2022 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/5f9c9b14740569d1a4ca2991.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/auto-format-your-python-code-with-black/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Auto-Format Your Python Code with Black</a>
      </p><p>Escrever código em Python é uma coisa. Escrever o código em um formato bom é outra. Programadores júniores frequentemente focam em ter a certeza de que seus códigos estão funcionando e se esquecem de formatar o código corretamente ao longo do caminho.</p><p>Se você escreve um programa pequeno (com mil linhas de código) você, provavelmente, deixará a formatação do seu código para lá.</p><p>Porém, à medida que os programas ficam mais e mais complexos, eles ficam cada vez mais difíceis de entender. Em certo ponto (em torno de 15 mil linhas de código), fica difícil de entender o código que você mesmo escreveu.</p><p>A diferença entre trabalhar em um código bem formatado e em um código mal formatado é como a diferença entre morar em um palácio e morar em uma casa suja.</p><h1 id="por-que-formatar-seu-c-digo-em-python-importante"><strong><strong>Por que formatar seu código </strong>em <strong>Python é importante</strong>?</strong></h1><h3 id="legibilidade"><strong>Legibilidade</strong></h3><p>Formatar seu código ajudará você a <strong><strong>ler</strong></strong> seu código <strong><strong>de </strong>modo <strong>eficiente</strong></strong>. Ele parece mais organizado e, quando alguém olhar para ele, terá uma boa impressão.</p><h3 id="ajudar-em-suas-entrevistas-de-programa-o"><strong>Ajudará em suas entrevistas de programação</strong></h3><p>Quando você estiver em uma entrevista de programação, às vezes, os entrevistadores estarão atentos ao fato de você estar ou não formatando o código corretamente. Se você se esquecer dessa formatação, poderá perder sua perspectiva de emprego apenas por causa de seu código mal formatado.</p><h3 id="apoio-da-equipe"><strong>Apoio da equipe</strong></h3><p>Formatar seu código se torna mais importante quando você está trabalhando em uma <strong>equipe</strong>. Várias pessoas, provavelmente, estarão trabalhando no mesmo projeto de software. O código que você escreve deve ser entendido por seus colegas de equipe. Caso contrário, torna-se mais difícil trabalhar em conjunto.</p><h3 id="facilita-a-detec-o-de-bugs"><strong>Facilita a detecção de bugs</strong></h3><p>Um código mal formatado pode tornar extremamente difícil a detecção de bugs ou, até mesmo, trabalhar em um programa. Ele também é realmente horrível de se ver. <em>É uma ofensa aos seus olhos.</em></p><h1 id="pylint-e-flake8"><strong><strong>Pylint </strong>e<strong> Flake8</strong></strong></h1><p>A maioria dos desenvolvedores em Python gosta de usar o <a href="https://www.pylint.org/" rel="noopener nofollow">Pylint</a> ou o <a href="http://flake8.pycqa.org/en/latest/">Flake8</a> para verificar seus códigos quanto a erros e regras de estilo.</p><p>O <strong><strong><strong><strong>Pylint</strong></strong></strong></strong> é uma ferramenta que verifica erros em Python. Ele tenta impor um padrão de codificação e procura por coisas que "cheiram mal" no código. Ele também pode procurar por certos erros de tipo, recomendar sugestões sobre como determinados blocos podem ser refatorados e oferecer a você detalhes sobre a complexidade do código.</p><p>O <strong><strong><strong><strong>Flake8</strong></strong></strong></strong> é uma biblioteca do Python que engloba <strong><strong><strong><strong>PyFlakes</strong></strong></strong></strong>, <strong><strong><strong><strong>pycodestyle</strong></strong></strong></strong> e o <strong>script de McCabe, de Ned Batchelder</strong>. É um ótimo conjunto de ferramentas para verificar sua base de código em relação ao estilo de codificação <strong>(PEP8)</strong>, erros de programação como "biblioteca importada, mas não utilizada", "nome indefinido" e código que não está sendo indentado adequadamente.</p><p>O problema é que essas ferramentas apenas relatam os problemas que identificam no código-fonte e deixam o fardo de corrigi-los para os desenvolvedores do Python!</p><p>Se tivéssemos uma ferramenta que pudesse identificar e resolver o problema ao mesmo tempo, não seria ótimo? O <strong>Black</strong> é uma ferramenta que permite que você <strong>identifique erros</strong> e <strong>formate seu código em Python</strong> ao mesmo tempo. Assim, você se torna mais produtivo.</p><h1 id="introdu-o-ao-black"><strong><strong><strong><strong>Introdu</strong></strong></strong>ção ao <strong><strong><strong>Black</strong></strong></strong></strong></h1><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/1_bxzXidSUpkEaj7j0rC5ygg.png" class="kg-image" alt="1_bxzXidSUpkEaj7j0rC5ygg" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/1_bxzXidSUpkEaj7j0rC5ygg.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/1_bxzXidSUpkEaj7j0rC5ygg.png 700w" width="700" height="329" loading="lazy"><figcaption>Logotipo do Black</figcaption></figure><p>Do README do projeto:</p><blockquote>Ao usar o Black, você concorda em ceder o controle sobre as minúcias da formatação manual. Em troca, o Black oferece a você velocidade, determinismo e liberdade do pycodestyle reclamando da formatação. Você economizará tempo e energia mental para assuntos mais importantes.</blockquote><p>O Black pode reformatar seu arquivo inteiro adequadamente, de acordo com o estilo de código do Black. Isso ajuda seu cérebro a se concentrar no problema que você quer resolver e em programar soluções, em vez de se distrair com a estrutura do código e com pequenas diferenças estilísticas.</p><p>Então, vamos ver como usá-lo.</p><h3 id="instalar-o-black"><strong><strong>Instal</strong>ar o<strong> Black</strong></strong></h3><p>O Black pode ser instalado executando <code>pip install black</code>. Ele requer a versão 3.6.0 do Python ou superior para ser executado. Assim que o Black estiver instalado, você terá uma nova ferramenta de linha de comando chamada Black disponível em seu terminal e estará pronto para começar!</p><p>Para começar imediatamente com padrões sensatos, escolha o arquivo em Python que deseja formatar e, em seguida, escreva <strong>black filename.py</strong> no terminal. O Black, então, formatará seu arquivo em Python.</p><p>Agora, veremos o que o Black pode nos ajudar a fazer.</p><h3 id="formatar-um-nico-arquivo"><strong><strong>Format</strong>ar um único arquivo</strong></h3><p>Vejamos este exemplo simples: aqui estão minhas duas funções no meu arquivo em Python, chamado sample_code.py.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/1_OKkCLUmuspv8IHiU25NVTw.png" class="kg-image" alt="1_OKkCLUmuspv8IHiU25NVTw" width="373" height="354" loading="lazy"><figcaption>sample_code.py</figcaption></figure><p>Você pode usar <code>black sample_code.py</code> no terminal para mudar o formato. Após executar o Black, você verá a seguinte saída:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/d.png" class="kg-image" alt="d" width="436" height="63" loading="lazy"></figure><p>Em seguida, abra o arquivo sample_code.py para ver o código em Python formatado:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/e.png" class="kg-image" alt="e" width="398" height="283" loading="lazy"></figure><p>O código em Python, agora, está formatado e mais legível.</p><h3 id="formatar-m-ltiplos-arquivos"><strong><strong>Format</strong>ar múltiplos arquivos</strong></h3><p>Para formatar mais de um arquivo em Python, escreva <code>black nome_da_pasta/</code> no terminal.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/f.png" class="kg-image" alt="f" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/f.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/f.png 638w" width="638" height="120" loading="lazy"><figcaption>Formata todos os arquivos em Python dentro da pasta</figcaption></figure><p>Três arquivos em Python dentro da pasta chamada python_with_black foram reformatados.</p><h3 id="verificando-arquivos-para-formata-o"><strong>Verificando arquivos para formatação</strong></h3><p>Se você não quer que o Black altere seu arquivo, mas quer saber se ele acha que um arquivo deveria ser alterado, você pode usar um dos seguintes comandos:</p><p><code>black --check .</code>: esse comando verificará quais arquivos em Python podem ser formatados na pasta atual (mas não os modifica).</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/g.png" class="kg-image" alt="g" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/g.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/g.png 623w" width="623" height="119" loading="lazy"><figcaption>Verifica arquivos para formatar</figcaption></figure><p><code>black --check --diff file_name.py </code>: esse comando mostra o que precisa ser feito no arquivo, mas não o modifica.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/h.png" class="kg-image" alt="h" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/h.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/h.png 700w" width="700" height="530" loading="lazy"><figcaption>Verifica diferenças após a formatação</figcaption></figure><h3 id="alterar-o-n-mero-de-caracteres-por-linha"><strong>Alterar o número de caracteres por linha</strong></h3><p>Observe que o padrão do Black é de 88 caracteres para o comprimento da linha, mas você pode alterar isso usando a opção <code>-l</code> ou <code>- -line-length</code>.</p><p>Por exemplo, para alterar para 60 caracteres: <code>black -l 60 python_file.py</code>.</p><h1 id="black-no-jupyter-notebook"><strong><strong>Black </strong>no<strong> Jupyter Notebook</strong></strong></h1><p>Para usuários do Jupyter Notebook, você ainda pode formatar automaticamente seu código em Python com esta simples extensão chamada Jupyter Black. Esta extensão reformata/embeleza o código em uma célula de código do Notebook usando o Black.</p><p>A extensão Jupyter Black fornece</p><ul><li>Um botão para a barra de ferramentas.</li><li>Um atalho de teclado para reformatar a célula de código atual (padrão: Ctrl-B).</li><li>Um atalho de teclado para reformatar todas as células de código (padrão: Ctrl-Shift-B).</li></ul><h3 id="instalar-o-jupyter-black"><strong><strong>Instal</strong>ar o<strong> Jupyter Black</strong></strong></h3><p>Primeiro, assegure-se de ter instalado <a href="https://github.com/ipython-contrib/jupyter_contrib_nbextensions" rel="noopener nofollow">jupyter-contrib-nbextensions</a> e <a href="https://black.readthedocs.io/en/stable/" rel="noopener nofollow">black</a>. Então, execute os seguintes comandos.</p><pre><code>jupyter nbextension install https://github.com/drillan/jupyter-black/archive/master.zip — user</code></pre><p>Em seguida, habilite a extensão executando:</p><pre><code>jupyter nbextension enable jupyter-black-master/jupyter-black
</code></pre><p>Agora, você pode começar a formatar seu código em Python em cada célula do Notebook.</p><p>Primeiro, selecione a célula do notebook na qual você deseja formatar seu código em Python. Em seguida, clique no botão de extensão chamado Black.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/i.png" class="kg-image" alt="i" width="476" height="409" loading="lazy"><figcaption>Antes de usar Jupyter Black</figcaption></figure><p>Então, selecione o botão Jupyter Black:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/j.png" class="kg-image" alt="j" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/j.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/j.png 700w" width="700" height="60" loading="lazy"><figcaption>Botão Jupyter Black</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/k.png" class="kg-image" alt="k" width="397" height="246" loading="lazy"><figcaption>Depois de usar Jupyter Black</figcaption></figure><h1 id="integra-o-com-o-editor"><strong>Integração com o e<strong>ditor</strong></strong></h1><p>Você pode integrar o Black com os seus editores favoritos. Atualmente, o Black suporta PyCharm/IntelliJ IDEA, Wing IDE, Vim, Visual Studio Code, Sublime Text 3, Atom/Nuclide, Kakoune e Thonny. Siga as instruções <a href="https://black.readthedocs.io/en/latest/editor_integration.html">aqui</a> para integrar o Black com seu editor favorito (texto em inglês).</p><p>Se você quiser aprender mais sobre o Black, recomendo assistir a palestra de Łukasz Langa na <a href="https://youtu.be/esZLCuWs_2Y" rel="noopener nofollow">PyCon 2019</a> (em inglês).</p><p>Se você aprendeu algo novo ou gostou de ler este artigo, compartilhe-o para que outras pessoas possam vê-lo. Até lá, nos vemos na próxima publicação! Você também pode encontrar o autor pelo <a href="https://twitter.com/Davis_McDavid">Twitter</a>.</p> ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
