Subiendo imágenes en React Native y Firebase con React
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
}
Salto La Golondrina, municipio Salcedo, provincia de Hermanas Mirabal, República Dominicana
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.Creación de diccionario griego con React Native: Planteamiento y creación del ambiente Pate 1
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
React Warning: Cannot update a component from inside the function body of a different component
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:
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("
1 comentario :
Publicar un comentario