<?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>Forem: Andrés Villanueva</title>
    <description>The latest articles on Forem by Andrés Villanueva (@villanuevand).</description>
    <link>https://forem.com/villanuevand</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%2F305839%2Fa3fc1491-d43f-4078-a24f-4d5b70161b3f.jpg</url>
      <title>Forem: Andrés Villanueva</title>
      <link>https://forem.com/villanuevand</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/villanuevand"/>
    <language>en</language>
    <item>
      <title>🖼️ Imágenes personalizadas con Firebase Cloud Functions y Gravatar.</title>
      <dc:creator>Andrés Villanueva</dc:creator>
      <pubDate>Fri, 10 Mar 2023 15:32:47 +0000</pubDate>
      <link>https://forem.com/villanuevand/imagenes-personalizadas-con-firebase-cloud-functions-y-gravatar-23c4</link>
      <guid>https://forem.com/villanuevand/imagenes-personalizadas-con-firebase-cloud-functions-y-gravatar-23c4</guid>
      <description>&lt;p&gt;Firebase Authentication nos proporciona un número  de proveedores que nos permiten autenticar usuarios en nuestra aplicación rápidamente y sin tener que invertir tiempo en revisar la documentación de cada uno de ellos para entender cómo interactuar con sus API. Esto nos permite centrarnos más en desarrollar un producto más agradable para los usuarios y eficiente a nivel de performance y arquitectura aprovechando las bondades de la plataforma. &lt;/p&gt;

&lt;p&gt;Estos son los proveedores de identidad disponibles en Firebase hasta el momento de la publicación de este articulo&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fufhwbuyvfmejk490cuib.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fufhwbuyvfmejk490cuib.png" alt="Proveedores de Identidad de Firebase" width="800" height="303"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cada uno de ellos nos proporcionará toda la información disponible  que el proveedor posee sobre ese usuario, cuando hablo de información estoy haciendo referencia a información básica  no sensible del usuario, como por ejemplo: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Nombre&lt;/li&gt;
&lt;li&gt;Correo electrónico.&lt;/li&gt;
&lt;li&gt;Imagen de perfil.&lt;/li&gt;
&lt;li&gt;entre otros…&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Con toda la info podemos personalizar las sesiones de los usuarios y brindar una experiencia más agradable, con el fin de promover el uso de la aplicación, atraer mas usuarios y por ende incrementar las ventas. Pero, que pasa con aquellos proveedores que no retornan en su data información útil para nuestra causa?,  como por ejemplo una imagen de perfil. &lt;/p&gt;

&lt;p&gt;Un caso común de este escenario sería utilizar la creación de un nuevo usuario por &lt;a href="https://firebase.google.com/docs/auth/web/password-auth?hl=es"&gt;correo electrónico y contraseña&lt;/a&gt;. Para ello vamos a usar las &lt;a href="https://firebase.google.com/docs/functions/use-cases?hl=es_419"&gt;Firebase Cloud Functions&lt;/a&gt;, con los &lt;a href="https://firebase.google.com/docs/functions/auth-events"&gt;triggers o disparadores de Autenticación&lt;/a&gt;, más específicamente &lt;code&gt;onCreate()&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Según la documentación, este trigger se ejecutará cuando:&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Un usuario crea una cuenta de correo electrónico y una contraseña.&lt;/li&gt;
&lt;li&gt;Un usuario accede por primera vez con un proveedor de identidad federada.&lt;/li&gt;
&lt;li&gt;El desarrollador crea una cuenta con el SDK de Firebase Admin.&lt;/li&gt;
&lt;li&gt;Un usuario accede a una sesión de autenticación anónima por primera vez.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Un evento Cloud Functions &lt;em&gt;no&lt;/em&gt; se activa cuando un usuario accede por primera vez con un token personalizado&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;La función &lt;code&gt;onCreate&lt;/code&gt; espera 2 argumentos como parámetros:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;user,&lt;/strong&gt; de tipo &lt;a href="https://firebase.google.com/docs/reference/admin/node/firebase-admin.auth.userrecord"&gt;UserRecord&lt;/a&gt;, con el cual tendremos acceso a los atributos del usuario.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;context&lt;/strong&gt;, de tipo &lt;a href="https://firebase.google.com/docs/reference/functions/firebase-functions.eventcontext.md#eventcontext_interface"&gt;EventContext&lt;/a&gt;, donde tendremos la información del contexto del evento en la función que se esta ejecutando.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;functions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;user&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;onCreate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UserRecord&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;EventContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="c1"&gt;// Acá va la lógica &lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si bien la función espera 2 argumentos, en segundo,&lt;code&gt;context&lt;/code&gt; es opcional.  Una vez que el &lt;code&gt;onCreate&lt;/code&gt; se ejecuta tenemos que verificar si la propiedad &lt;code&gt;photoURL&lt;/code&gt; dentro del para tiene algún valor o no para proceder a agregarle nuestra imagen por defecto.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;functions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;user&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;onCreate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UserRecord&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;EventContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Usuario original&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;updateUserInfo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;photoURL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="c1"&gt;// Acá va la lógica&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="nx"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Se actualizo correctamente&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;updateUserInfo&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hubo un error en la función newUser&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;});&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ahora, qué opciones tenemos?.&lt;/p&gt;

&lt;h2&gt;
  
  
  Imagen estática de una CDN
&lt;/h2&gt;

&lt;p&gt;Esta es la opción más utilizada y sencilla a la hora de agregar una imagen personalizada a un nuevo usuario. Lo único que debemos hacer es alojar la imagen que deseemos mostrar en alguna CDN y una vez que se creen un nuevo usuario, asignarle a la propiedad &lt;code&gt;photoUrl&lt;/code&gt;, la direccción absoluta de la imagen alojado en la CDN.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;functions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;user&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;onCreate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UserRecord&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;EventContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Usuario original&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;updateUserInfo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;photoURL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;updateUserInfo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;admin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;updateUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;uid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;photoURL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://firebase.google.com/static/images/homepage/home-icon-release_2x.png&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
            &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="nx"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Se actualizo correctamente&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;updateUserInfo&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hubo un error en la función newUser&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si queremos llevar nuestra experiencia de usuario al siguiente nivel podemos usar algunas opciones que nos da &lt;strong&gt;&lt;a href="https://es.gravatar.com/"&gt;Gravatar&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Qué es Gravatar?
&lt;/h2&gt;

&lt;p&gt;Según Wikipedia Gravatar: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Es un servicio que ofrece un avatar único globalmente&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Este permite asociar una dirección de correo electrónica a una imagen y así poder tener una misma imagen en distintas plataformas.&lt;/p&gt;

&lt;p&gt;Esta plataforma nos permite crear imágenes aleatorias basadas en un hash &lt;a href="https://en.wikipedia.org/wiki/MD5"&gt;MD5&lt;/a&gt; de un correo electrónico, brindando la libertad de elegir entre: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Siluetas&lt;/li&gt;
&lt;li&gt;Patrónes geométricos (&lt;a href="https://en.wikipedia.org/wiki/Identicon"&gt;identicon&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;Mounstruos.&lt;/li&gt;
&lt;li&gt;Robots, entre otros.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl7e34iqpqs0oefhheqhx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl7e34iqpqs0oefhheqhx.png" alt="Tipos de imagenes aleatorias - Gravatar" width="800" height="123"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Si quieres conocer cuales son todos los tipos de imágenes aleatoria que puedes usar te recomiendo &lt;a href="https://en.gravatar.com/site/implement/images/"&gt;visitar este link&lt;/a&gt;. El próximo paso seria implementar un tipo de estas imágenes en nuestra cloud function. &lt;/p&gt;

&lt;h2&gt;
  
  
  Imagen personalizadas con Gravatar + Cloud Functions
&lt;/h2&gt;

&lt;p&gt;Para este ejemplo hemos decidido implementar los patrones geométricos o &lt;a href="https://en.wikipedia.org/wiki/Identicon"&gt;Identicon&lt;/a&gt; a todos los usuarios que creemos en nuestra aplicación, y para ellos debemos armar una URL siguiendo el siguiente patron:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;https://www.gravatar.com/avatar/{hash-md5-email}.jpg?d={tipo-imagen}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Para crear el hash md5 vamos a utilizar el paquete &lt;a href="https://www.npmjs.com/package/ts-md5"&gt;ts-md5&lt;/a&gt; en NPM. En este ejemplo estamos usando ts-md5 porque he configurado mis cloud functions en typescript Si en tu proyecto no estás usando typescript puedes buscar una librería que mas te agrade o se ajuste a tus necesidades.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;functions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;user&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;onCreate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UserRecord&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;EventContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Usuario original&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;updateUserInfo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Md5&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hashStr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;photoURL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;updateUserInfo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;admin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;updateUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;uid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;photoURL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`https://www.gravatar.com/avatar/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.jpg?d=identicon`&lt;/span&gt;
            &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="nx"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Se actualizo correctamente&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;updateUserInfo&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hubo un error en la función newUser&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;});&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En la línea 5, se puede ver cómo se hace la creación del hash md5 basado en la dirección de correo del usuario. En la línea 8 le asignamos al campo &lt;code&gt;photoUrl&lt;/code&gt; la url de siguiendo el patron que nos indica gravatar, con el hash del email y el tipo de imagen que deseamos crear. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://gist.github.com/Villanuevand/2ff04d801fc2b551cb506cf9c5ada854"&gt;En este link&lt;/a&gt; te voy a dejar el fragmento de código de la cloud function.&lt;/p&gt;

&lt;p&gt;Cuentame como te fue en la implementación de esta funcionalidad. &lt;/p&gt;

&lt;p&gt;Si te gustó no olvides hacermelo saber con un like o compartiendo tus impresiones conmigo en twitter, donde me puedes conseguir como &lt;a href="https://twitter.com/villanuevand"&gt;@villanuevand&lt;/a&gt; o enviando un mail a &lt;br&gt;
&lt;a href="mailto:name@gmail.com"&gt; &lt;/a&gt;&lt;a href="mailto:heypana@villanuevand.dev"&gt;heypana@villanuevand.dev&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Nos vemos en el próximo post mis panas. &lt;/p&gt;

</description>
      <category>firebase</category>
      <category>programming</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
