2
respostas

[Bug] Crash quando tento subir imagem

Após a aula 3.4 o aplicativo crasha sempre que tento subir uma imagem da galeria. Isso não acontece quando eu subo a imagem pardrão de galaxia.

Código do Post:

import { useState } from "react";
import {
  View,
  Text,
  TextInput,
  ScrollView,
  TouchableOpacity,
  SafeAreaView,
  Image,
} from "react-native";
import {
  salvarPost,
  atualizarPost,
  deletarPost,
} from "../../servicos/firestore";
import estilos from "./estilos";
import { entradas } from "./entradas";
import { alteraDados } from "../../utils/comum";
import { IconeClicavel } from "../../componentes/IconeClicavel";
import { salvarImagem } from "../../servicos/storage";
import * as ImagePicker from "expo-image-picker";

import uploadImagemPadrao from "../../assets/upload.jpeg";

const imagemGalaxia =
  "https://img.olhardigital.com.br/wp-content/uploads/2022/01/via-lactea-filamento-hidrogenio-capa.jpg";

export default function Post({ navigation, route }) {
  const [desabilitarEnvio, setDesabilitarEnvio] = useState(false);
  const { item } = route?.params || {};

  const [post, setPost] = useState({
    titulo: item?.titulo || "",
    fonte: item?.fonte || "",
    descricao: item?.descricao || "",
    imagemUrl: item?.imagemUrl || null,
  });
  const [imagem, setImagem] = useState(null);

  async function salvar() {
    setDesabilitarEnvio(true);

    if (item) {
      await atualizarPost(item.id, post);
      return navigation.goBack();
    }
    const postId = await salvarPost({ ...post, imagemUrl: "" });
    navigation.goBack();

    if (imagem != null) {
      const url = await salvarImagem(imagem, postId);
      await atualizarPost(postId, { ...post, imagemUrl: url });
    }
  }

  async function selecionarImagem() {
    let result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.Images,
      allowsEditing: true,
      quality: 1,
    });

    console.log(result.assets[0]);

    if (!result.canceled) {
      setImagem(result.assets[0].uri);
    }
  }

  return (
    <SafeAreaView style={estilos.container}>
      <View style={estilos.containerTitulo}>
        <Text style={estilos.titulo}>{item ? "Editar post" : "Novo Post"}</Text>
        <IconeClicavel
          exibir={!!item}
          onPress={() => {
            deletarPost(item.id);
            navigation.goBack();
          }}
          iconeNome="trash-2"
        />
      </View>
      <ScrollView style={{ width: "100%" }}>
        {entradas?.map((entrada) => (
          <View key={entrada.id}>
            <Text style={estilos.texto}>{entrada.label}</Text>
            <TextInput
              value={post[entrada.name]}
              placeholder={entrada.label}
              multiline={entrada.multiline}
              onChangeText={(valor) =>
                alteraDados(entrada.name, valor, post, setPost)
              }
              style={[
                estilos.entrada,
                entrada.multiline && estilos.entradaDescricao,
              ]}
            />
          </View>
        ))}

        <TouchableOpacity style={estilos.imagem} onPress={selecionarImagem}>
          <Image
            source={imagem ? { uri: imagem } : uploadImagemPadrao}
            style={estilos.imagem}
          />
        </TouchableOpacity>
      </ScrollView>

      <TouchableOpacity
        style={estilos.botao}
        onPress={salvar}
        disabled={desabilitarEnvio}
      >
        <Text style={estilos.textoBotao}>Salvar</Text>
      </TouchableOpacity>
    </SafeAreaView>
  );
}

Codigo do storage.js:

import { storage } from "../config/firebase";
import { ref, uploadBytes, getDownloadURL } from "firebase/storage";

export async function salvarImagem(imagem, nomeImagem) {
  if (!imagem) return;
  const downloadImagem = await fetch(imagem);
  const blobImagem = await downloadImagem.blob();
  const imagemRef = ref(storage, `posts/${nomeImagem}.png`);

  try {
    await uploadBytes(imagemRef, blobImagem);
    const url = await getDownloadURL(imagemRef);
    return url;
  } catch (error) {
    console.log(error);
    return null;
  }
}
2 respostas

Olá, Lorenzo!

Pelo que você descreveu, o aplicativo está funcionando corretamente quando você utiliza a imagem padrão de galáxia, mas apresenta problemas quando você tenta subir uma imagem da galeria, correto?

Uma possibilidade é que o problema esteja relacionado com as permissões para acessar a galeria de imagens do dispositivo. O módulo expo-image-picker requer permissões para acessar a galeria de imagens e, se essas permissões não forem concedidas, pode ser a causa do crash.

Você pode verificar se as permissões foram concedidas adicionando o seguinte código antes de chamar a função ImagePicker.launchImageLibraryAsync:

const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
if (status !== 'granted') {
  alert('Desculpe, precisamos de permissões de câmera para fazer isso funcionar!');
  return;
}

Este código solicita as permissões necessárias para acessar a galeria de imagens e, se as permissões não forem concedidas, exibe um alerta e interrompe a execução da função.

Caso isso não resolva, uma outra possibilidade é que o problema esteja relacionado com o tamanho ou formato da imagem que você está tentando subir. Você poderia verificar se o problema ocorre com todas as imagens ou apenas com algumas específicas?

Espero ter ajudado e bons estudos!

Olá, Matheus!

Testei com esse código porém não resolveu o problema. Creio que seja isso que você falou mesmo, algo com o tamanho ou tipo da imagem. Estou usando Mac e usando as fotos padrões da galeria e esse crash acontece com todas menos uma. As que dão erro são as que passam do limite de corte na edição (a foto maior corta mas vai). Testei no celular também (android) e o erro continuou. Agora não sei se é a extensão da imagem (.jpg ou .png) ou tamanho.

Muito obrigado.