<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Homer López Vidal</title>
    <description>The latest articles on DEV Community by Homer López Vidal (@napsterh).</description>
    <link>https://dev.to/napsterh</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F955485%2F1080fa1c-e174-413d-9cb9-5076d166d028.jpeg</url>
      <title>DEV Community: Homer López Vidal</title>
      <link>https://dev.to/napsterh</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/napsterh"/>
    <language>en</language>
    <item>
      <title>Envío de Email con Firebase Functions y Nodemailer</title>
      <dc:creator>Homer López Vidal</dc:creator>
      <pubDate>Wed, 21 Jun 2023 18:21:52 +0000</pubDate>
      <link>https://dev.to/napsterh/envio-de-email-con-firebase-functions-y-nodemailer-79p</link>
      <guid>https://dev.to/napsterh/envio-de-email-con-firebase-functions-y-nodemailer-79p</guid>
      <description>&lt;p&gt;En esta publicación trataré de explicar el uso de Firebase Functions junto a Nodemailer para el envío de correos electrónicos. Actualmente estoy trabajando en un proyecto que se requiere la implementación de una funcionalidad que envíe un correo al realizar una acción como es el registro por formulario de un usuario. A continuación explicaré los pasos para la implementación.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Instalación&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Consideración 1:&lt;/strong&gt; Para este caso usaremos un &lt;a href="https://create-react-app.dev/docs/getting-started"&gt;proyecto React&lt;/a&gt; para el formulario de registro.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Consideración 2:&lt;/strong&gt; Antes del primer paso, se asume que ya se cuenta con un &lt;a href="https://cloud.google.com/firestore/docs/client/get-firebase?hl=es-419"&gt;proyecto creado de firebase&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Paso 1:&lt;/strong&gt; Instalación de Firebase CLI&lt;/p&gt;

&lt;p&gt;Para poder usar todas las funcionalidades de Firebase en nuestro proyecto, tenemos que instalar via NPM las dependencias y funcionalidades. En la terminal ingresamos el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -g firebase-tools
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Después de instalar, iniciamos sesión con nuestra cuenta de Google Firebase mediante el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;firebase login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Paso 2:&lt;/strong&gt; Inicializando el proyecto desde Firebase&lt;/p&gt;

&lt;p&gt;Después de iniciar sesión en Firebase, ejecutaremos el comando para iniciar con la configuración y crear la función. Ingrese el siguiente comando en la raíz del proyecto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;firebase init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nos mostrará una lista de todos los servicios que tiene Firebase, en este caso seleccionaremos Functions(recuerda navegar por comando con las flechas de arriba y abajo, seleccionar con ‘space’ y continuar con ‘enter’):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--py14JF_1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/93uj1lebjvsmraukipub.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--py14JF_1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/93uj1lebjvsmraukipub.png" alt="firebase tools" width="800" height="359"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Después, seleccionamos un proyecto ya existente en firebase(en caso contrario puedes crear primero el proyecto en Firebase console como lo expliqué lineas arriba):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wyCty5IC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/od43bgaokfulnchgwnkz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wyCty5IC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/od43bgaokfulnchgwnkz.png" alt="Seleccionar proyecto" width="800" height="200"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Seleccionamos nuestro proyecto de prueba:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kNsdERnc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jhmzao5thxm2bfm0phge.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kNsdERnc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jhmzao5thxm2bfm0phge.png" alt="Proyecto seleccionado" width="448" height="169"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;y a continuación nos solicitará en que lenguaje queremos instalar(en este caso usaremos &lt;strong&gt;JavaScript&lt;/strong&gt;), después nos consultará por el uso de &lt;strong&gt;ESLint&lt;/strong&gt; para capturar posibles bugs, en este caso tampoco lo usaremos y finalmente nos solicitará la instalación de dependencias necesarias desde NPM, en este caso le daremos en &lt;strong&gt;sí&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Finalmente tendremos instalado una nueva carpeta llamada functions donde trabajaremos en el archivo index.js&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--66Znef5B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i6j0t4f8e6z8llwfyf6e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--66Znef5B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i6j0t4f8e6z8llwfyf6e.png" alt="Functions" width="800" height="376"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Paso 3:&lt;/strong&gt; Configuración de Functions Firebase en el index.js&lt;/p&gt;

&lt;p&gt;Antes debemos instalar la dependencia de &lt;a href="https://nodemailer.com/about/"&gt;Nodemailer&lt;/a&gt;, para eso usamos la linea de comando y nos vamos hasta la carpeta functions y ejecutamos el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install nodemailer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Después de instalarlo, podemos continuar con el primer paso en el archivo &lt;strong&gt;index.js&lt;/strong&gt; de la functions, para eso importamos la dependencia de firebase-functions y nodemailer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const functions = require("firebase-functions");
const nodemailer = require("nodemailer");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Creamos la función &lt;strong&gt;transport&lt;/strong&gt; donde agregaremos el servicio de correo electrónico que usaremos y las credenciales de autentificación(en las ultimas políticas de Google, se pide crear una contraseña de aplicaciones para poder acceder a Gmail desde un servicio de terceros, créalo &lt;a href="https://support.google.com/accounts/answer/185833?hl=es-419"&gt;de esta manera&lt;/a&gt; )&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const transport = nodemailer.createTransport({
   service: "Gmail",
   auth: {
      user: "user@gmail.com",
      pass: "hkjUIjhkKBJHkjadfg",
   },
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Después, creamos una función que se activará al crear una nueva colección en firebase:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;exports.emailSuccess = functions.firestore
   .document("userRegister/{id}")
   .onCreate(async (snap) =&amp;gt; {
      const getData = snap.data();
      const email = await getData.email;
      return sendSuccess(email);
   });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;el &lt;strong&gt;userRegister&lt;/strong&gt; viene a ser la colección donde estamos guardando los usuarios registrados desde un formulario y nuestra función se activará cada vez que exista un nuevo registro o &lt;strong&gt;snap&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Capturamos el atributo &lt;strong&gt;email&lt;/strong&gt; que fue registrado desde el formulario y lo mandamos como parámetro a la función sendSuccess.&lt;/p&gt;

&lt;p&gt;Finalmente creamos la etiqueta HTML dentro de la función sendSuccess de la siguiente manera:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const sendSuccess = (email) =&amp;gt; {
   return transport
      .sendMail({
            from: "Napster.dev &amp;lt;napster@gmail.com&amp;gt;",
            to: email,
            subject: "Hola mundo",
            html: `
            &amp;lt;!DOCTYPE html&amp;gt;
               &amp;lt;html lang="en"&amp;gt;
               &amp;lt;head&amp;gt;
                  &amp;lt;meta charset="UTF-8"&amp;gt;
                  &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&amp;gt;
                  &amp;lt;title&amp;gt;Email de ejemplo&amp;lt;/title&amp;gt;
               &amp;lt;/head&amp;gt;
               &amp;lt;body style="font-family: Arial, sans-serif;"&amp;gt;
                  &amp;lt;table style="width: 100%; max-width: 600px; margin: 0 auto; border-collapse: collapse;"&amp;gt;
                     &amp;lt;tr&amp;gt;
                           &amp;lt;td style="background-color: #f1f1f1; padding: 20px; text-align: center;"&amp;gt;
                              &amp;lt;h1&amp;gt;Bienvenido al ejemplo de correo electrónico&amp;lt;/h1&amp;gt;
                           &amp;lt;/td&amp;gt;
                     &amp;lt;/tr&amp;gt;
                     &amp;lt;tr&amp;gt;
                           &amp;lt;td style="padding: 20px;"&amp;gt;
                              &amp;lt;p&amp;gt;Hola,&amp;lt;/p&amp;gt;
                              &amp;lt;p&amp;gt;Este es un correo electrónico de ejemplo.&amp;lt;/p&amp;gt;
                           &amp;lt;/td&amp;gt;
                     &amp;lt;/tr&amp;gt;
                  &amp;lt;/table&amp;gt;
               &amp;lt;/body&amp;gt;
               &amp;lt;/html&amp;gt;
               `,
      })
      .then((r) =&amp;gt; r)
      .catch((e) =&amp;gt; e);
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para el despliegue de la función en firebase, ingresamos el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;firebase deploy --only functions 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esto hará desplegar solo la carpeta functions(Recuerda que para hacer el despliegue tienes que tener un plan Blaze de pago en firebase ).&lt;/p&gt;

&lt;p&gt;Este es el código completo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const functions = require("firebase-functions");
const nodemailer = require("nodemailer");

const transport = nodemailer.createTransport({
   service: "Gmail",
   auth: {
      user: "user@gmail.com",
      pass: "hkjUIjhkKBJHkjadfg",
   },
});

exports.emailSuccess = functions.firestore
   .document("userRegister/{id}")
   .onCreate(async (snap) =&amp;gt; {
      const getData = snap.data();
      const email = await getData.email;
      return sendSuccess(email);
   });

const sendSuccess = (email) =&amp;gt; {
   return transport
      .sendMail({
            from: "Napster.dev &amp;lt;napster@gmail.com&amp;gt;",
            to: email,
            subject: "Hola mundo",
            html: `
            &amp;lt;!DOCTYPE html&amp;gt;
               &amp;lt;html lang="en"&amp;gt;
               &amp;lt;head&amp;gt;
                  &amp;lt;meta charset="UTF-8"&amp;gt;
                  &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&amp;gt;
                  &amp;lt;title&amp;gt;Email de ejemplo&amp;lt;/title&amp;gt;
               &amp;lt;/head&amp;gt;
               &amp;lt;body style="font-family: Arial, sans-serif;"&amp;gt;
                  &amp;lt;table style="width: 100%; max-width: 600px; margin: 0 auto; border-collapse: collapse;"&amp;gt;
                     &amp;lt;tr&amp;gt;
                           &amp;lt;td style="background-color: #f1f1f1; padding: 20px; text-align: center;"&amp;gt;
                              &amp;lt;h1&amp;gt;Bienvenido al ejemplo de correo electrónico&amp;lt;/h1&amp;gt;
                           &amp;lt;/td&amp;gt;
                     &amp;lt;/tr&amp;gt;
                     &amp;lt;tr&amp;gt;
                           &amp;lt;td style="padding: 20px;"&amp;gt;
                              &amp;lt;p&amp;gt;Hola,&amp;lt;/p&amp;gt;
                              &amp;lt;p&amp;gt;Este es un correo electrónico de ejemplo.&amp;lt;/p&amp;gt;
                           &amp;lt;/td&amp;gt;
                     &amp;lt;/tr&amp;gt;
                  &amp;lt;/table&amp;gt;
               &amp;lt;/body&amp;gt;
               &amp;lt;/html&amp;gt;
               `,
      })
      .then((r) =&amp;gt; r)
      .catch((e) =&amp;gt; e);
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>firebase</category>
      <category>node</category>
      <category>googlecloud</category>
      <category>react</category>
    </item>
  </channel>
</rss>
