mayo 2021

Pedro Lara {Dev}

Código, Libros y Podcast

Subiendo imágenes en React Native y Firebase con React

1 comentario

Pedro Lara

En esta ocasión me propongo compartir estos pasos para subir  una una imagen en una aplicación creada con React Native y Expo. 

 


Para este ejemplo asumimos que ya disponemos de un proyecto creado en firebase con una ruta llamada “/imagenes” en la que vamos a guardar nuestras imágenes.

Lo primero que vamos a hacer es instalar las dependencias necesarias para poder hacer uso de la Gallery de nuestro teléfono:

expo install expo-permissions

También debemos instalar image Picker:

expo install expo-image-picker

 

Vamos a crear un componente llamado perfil_component y tres métodos que se encargarán de realizar todo el proceso dese validar los permisos de acceder a la galería de imágenes hasta enviar las imágenes a Firebase:

 

changePhoto()                    “Se ejecutará al presionar un icono para subir una imagen

loadImageFromGallery()   Se encargará validar los permisos de acceder a la        galería de imágenes de acceder a ella

uploadImage()                     Se encargará de subir la imagen a Firebase

fileToBlob()                          Se encargará de convertir la imagen a blob

updateProfile()                    Se encargará de actualizar la imagen en el perfil del usuario

 

1.    Creando el componenente perfil_component

 

Creamos un componente al que llamaremos perfil_component. En este nuevo componente vamos a hacer uso de un avatar que nos ofrece react. Hacemos el import desde react-native-elements:

perfil_component.js

import { Avatar } from 'react-native-elements';

import React from 'react';

import { Text, View, Image } from 'react-native';

import { Avatar } from 'react-native-elements';

 

 

export default function App() {

  return (

    <View>

      <Avatar

       rounded

       size= "large"

       source={{

       uri:

       'https://s3.amazonaws.com/uifaces/faces/twitter/ladylexy/128.jpg',

      }}

    />

    </View>

  );

}

El componente avatar recibe varios parámetros los cuales podemos ver en la documentación oficial, pero para nuestro caso, solo usaremos tres: rounded,  source y size.

Creamos un evento onPress en nuestro avatar para poder capturar cuando el usuario toque la imagen. Este evento onPress llamará una función que llamaremos onChangePhoto. Este método llamará a otro método llamado loadImageFromGallery el cual crearemos en nuestro Helpers:

 

import { Avatar } from 'react-native-elements';

import React from 'react';

import { Text, View, Image } from 'react-native';

import { Avatar } from 'react-native-elements';

 

 

export default function App() {

  return (

    <View>

      <Avatar

       rounded

       size= "large"

       source={{

       uri:

       'https://s3.amazonaws.com/uifaces/faces/twitter/ladylexy/128.jpg',

      }}

     onPress={()=>{

           changePhoto()}

       }

    />

    </View>

  );

}

2.    Creando el método changePhoto()

const changePhoto = async ()=>{

        const result = await loadImageFromGAllery([1,1])

        if(!result.status){

            return

        }

 

        const resultUploadImage = await uploadImage(result.image, "imagenes", user.uid)

        if(!resultUploadImage.statusResponse){

            setLoading(false)

            Alert.alert("Ha ocurrido un error al almacenar la imagen")

            return

 

        }

        const resultUpdateProfile = await updateProfile({protoURL: resultUploadImage.url})

        if(resultUpdateProfile.statusResponse){

           

            setPhotoURL(resultUploadImage.url)

           

        }else{

            Alert.alert("Ha ocurrido un error al actualizar la imagen de perfil")

        }

    }

 

3.    Creando el método loadImageFromGallery

El método loadImageFromGallery  se encargará de validar los permisos de acceder a la galería de imágenes así como cargar la imagen. En nuestro fichero helpers.js importamos la validación de permisos que nos ofrece expo, así como la función ImagePicker que nos permite acceder a las imágenes. Luego implementamos la subida de imágenes:

 

helpers.js

import * as Permissions from 'expo-permissions'

import * as ImagePicker from 'expo-image-picker'

 

Dentro de nuestro método loadImageFromGAllery creamos la implementación para acceder a la galería de imágenes de nuestro teléfono:

 

export const loadImageFromGAllery = async(array)  =>{

    const response = { status: false, images: null }

    const resultPermisions = await Permissions.askAsync(Permissions.CAMERA)

    if(resultPermisions.status == 'denied'){

        Alert('Debes de darle permisos para accedera la imagenes del telfono')

        return response

    }

    const result = await ImagePicker.launchImageLibraryAsync({

        allowsEditing: true,

        aspect: array

    })

    if(result.cancelled){

        return response

    }

    response.status = true

    response.iamge = result.uri

    return response;

}

La función Permissions.askAsync le pregunta al usuario si desea otorgar permisos de la Gallería de imagines a la aplicación.  Con el parámetro allowsEditing: true habitamos que el usuario pueda editar la imagen seleccionada. Con aspect: array le pasamos las dimensiones de la imagen. Con result.cancelled validamos si el usuario cancela la acción antes de guardar la imagen. Mientras que con result.uri obtenemos la ruta de la imagen seleccionada.

4.    Creando el método uploadImage()

export const uploadImage = async(image, path, name)=>{

     const result = {statusResponse: false, error: null, url:null}

     const ref = firebase.storage().ref(path).child(name)

     const blob = await fileToBlob(image)

    try{

        await ref.put(blob)

        const url = await firebase.storage().ref(`${path}/${name}`).getDownloadURL()

        result.statusResponse =true

        result.url = url

    }catch(error){

        result.error = error

        console.log(error)

    }

   

    return result

 

}

 

5.    Crenado e método fileToBlob()   

Aprovechamos y creamos otro método en nuestro fichero helper.js para convertir la imagen en blob.

export const fileToBlob = async(path)=>{

    const file = await fetch(path)

    const blob = await file.blob()

    return blob

}

 

 

6.    Creando el método updateProfile()

 

export const updateProfile = async(data)=>{

    const result = {statusResponse:true, error:null}

    try{

        await firebase.auth().currentUser.updateProfile(data)

    }catch(error){

        result.statusResponse = false

        result.error = error

    }

    console.log(result)

    return result

}

 

VIDEOS QUE TE PUEDEN INTERESAR:










1 comentario :

Publicar un comentario

Salto La Golondrina, municipio Salcedo, provincia de Hermanas Mirabal, República Dominicana

No hay comentarios
En el municipio de Salcedo, provincia de Hermanas Mirabal, República Dominicana, se encuentra el Salto La Golondrina, que junto a otros saltos conforman un hermoso lugar para pasarla bien. Estuve visitando el lugar por primera vez y creo que lo repetiré todas las veces que pueda. 

Ubicación: https://goo.gl/maps/KehiBMgJMBQZv17S7

La ruta de accesso no está en buenas condiciones, pero se puede transitar, sólo teniendo la precaución que en tiempos de lluvia puede haber mucho lodo que dificulta que los vehículos pueden pasar con facilidad. Luego, es necesario caminar hacia los saltos, un trayecto de alrededor de 30 minutos. Al llegar  vale la pena haber caminado, se disfruta mucho.



















No hay comentarios :

Publicar un comentario

Creación de diccionario griego con React Native: Planteamiento y creación del ambiente Pate 1

No hay comentarios

En esta ocasión vamos a crear una aplicación con React Native que consistirá en un diccionario Griego Koiné-Español. Este diccionario no sólo nos permitirá buscar palabras, sino que también nos mostrará el texto griego del Nuevo Testamento, y cuando el usuario haga clic en una palabra, mostrará su traducción y una lista de libros donde aparece la palabra seleccionada.

 

Además de mostrar la traducción de la palabra cliqueada, vamos a mostrar una lista de artículos y comentarios donde se habla acerca de los textos en los aparece dicha palabra.

 

Herramientas a Usar

 

1.Diccionario Griego Hebreo Strong api: https://github.com/openscriptures/strongs/blob/master/todo-diffs.txt

 

2. Texto griego del Nuevo Textamnete APi: https://github.com/tyndale/STEPBible-Data

 

3.  Api Blible https://scripture.api.bible/

 

Manos a la obra


Sigue: 

Creación de diccionario griego con React Native: Creación del api con Node Js, express, Firebase Functions y Firestore Parte 1



No hay comentarios :

Publicar un comentario

React Warning: Cannot update a component from inside the function body of a different component

No hay comentarios

Pedro Lara



A partir de la versión v16.13.0 de React, cuando se intenta actualizar un Hook de un componente desde el interior de otro nos muestra este warning: Warning: Cannot update a component from inside the function body of a different component

En mi caso particular, el error me aparece al intentar realizar el siguiente proceso:

Tengo un componente funcional que implementa un ListItem, si el usuario hace clic en este elemento debe llamar una función que muestra un console.log y actualiza un Hook useState. Sin embargo, esto no sucede, al contrario, me muestra el warning ya mencionado y no me actualiza el useState:

Aquí enlace el componente


import React, {useState} from 'react';

import { ListItem,Icon} from 'react-native-elements'

import { Alert, Modal, StyleSheet, Text, Pressable, View } from "react-native";

 

 

 

const OptionsAccount = ()=>{

   

    const [showModal, setShowModal] = useState(null)

    const [redeCompoenent, setRenderComponenet] = useState(null)

   

   

    const generateOptions =()=>{

        return =[

          {title: "Cambiar Nombre"

          iconNameLeft:"account-circle"

          iconColorLeft:"#DAF7A6"

          iconNameRight:"chevron-right"

          iconColorRight:"#DAF7A6"

          onPress: ()=>selectedComponent("name")

          },

          {title: "Cambiar Email"

          iconNameLeft:"account-circle"

          iconColorLeft:"#DAF7A6"

          iconNameRight:"chevron-right"

          iconColorRight:"#DAF7A6"

          onPress: ()=>selectedComponent("email")

          },

            {title: "Cambiar Password"

          iconNameLeft:"account-circle"

          iconColorLeft:"#DAF7A6"

          iconNameRight:"chevron-right"

          iconColorRight:"#DAF7A6"

          onPress: ()=>selectedComponent("password")

          }

           

        ]

    }

   

   

    const selectedComponenet = (key)=>{

         console.log(key)

       

        setShowModal(true)

    }

   

    const menuOptions = generateOptions();

    return(

   

    

          {

            list.map(menuOptions, (menu, index) => (

              

                

               

                

                  {menu.title}

                

       

                

               

              

            ))

          }

 

    

        

        Modal    

   

    )   

} 

const styles = StyleSheet.create({
   

}) 

export default OptionsAccount; 
 

Esto es estraño porque parecería que ahora no se puede realizar algo que hemos estado haciendo desde hace mucho tiempo, que además fue recomendado por el equipo de React.

He encontrado mucha información sobre este error, pero muy confusa y las soluciones que ofrecen no fueron efectivas en mi caso, por ejemplo, en https://flaviocopes.com/react-update-while-rendering-different-component/ dicen que colocando un Hook useEffect resuelve el problema, sin embargo, en mi caso no funcionó.

En este otro hilo se generó un acalorado debate en el que incluso intervino Dan Abramov creador de Redux. Pero, no ofrecen una solución efectiva en mi caso: https://github.com/facebook/react/issues/18178


En febrero del 2020 el equipo de React anunció sobre algunas advertencias que se presentarían en la versión 16.13.0: https://reactjs.org/blog/2020/02/26/react-v16.13.0.html


En mi caso, para resolver el problema,  procedí a pasarle el Hook setRednerComponent a la función selectedComponent:


onPress: ()=>selectedComponent("displayName", setRenderComponent )

Aquí el componente funcionando correctamente

No hay comentarios :

Publicar un comentario