프론트/React Native, React

[리액트네이티브] react-native firebase storage에 이미지 업로드 하기

연지양갱 2023. 6. 26. 22:25
728x90
반응형
SMALL

firebase 에서 storage를 생성한다

꼭!!!!!!!!!!

rules를 true로 해줘야지 올릴수 있음!!

안올라가서 뭐지 뭐지 했는데ㅜㅜ

완전 까먹었었음!

해당 내용은 아래 링크에서 참고하시오오오우

 

 

파이어베이스에서 지원하는 문서를 보면서 코드를 짜고 있다

요렇게 많은 코드를 실행해봤을 때

파이어베이스 문서는

쉽게 이해할 수 있도록 적은것 같으면서도 잘 모르겠다ㅏ...

내가 잘 못하는것같기두 하구

일단

백업이 중요해서,,,ㅎㅎ

일단

이미지를 업로드 하는 내용은 완료했다

하지만

이미지를 불러올 수 없어서

그리고

파이어베이스에서 사진을 미리 볼수도 없어서

문제가 있었다

저번 종프 중간 발표때 storage를 하셨다는 분이 있어서ㅓ

그분에게 사정해서

코드를 받았다!!

웬만해서 이해하겠는데

전체 코드가 아닌 해당 함수만 받고 주석이 없어서 조금 어려웠다!

그래도 이해해야함..

주신 콛드는 공유는 안하겠다ㅏ

내 전체코드,,,

담에 다시 저장할 건데

일단 백업으로 올려두겠다!

업로드 됐다는 log가 찍힌 코드

import React, { useState, useEffect } from 'react';
import { StyleSheet, Text, View, Button, Image, ScrollView } from 'react-native';
import { Camera } from 'expo-camera';
import * as ImagePicker from 'expo-image-picker';



// firestorage
import { getStorage, ref, uploadBytes, getDownloadURL } from "firebase/storage";


export default function Play(navigation) {
  const [hasCameraPermission, setHasCameraPermission] = useState(null);
  const [camera, setCamera] = useState(null);
  const [image, setImage] = useState(null);
  const [type, setType] = useState(Camera.Constants.Type.back);



  useEffect(() => {
    (async () => {
      console.log('CameraCheck useEffect')
      const cameraStatus = await Camera.requestCameraPermissionsAsync();
      setHasCameraPermission(cameraStatus.status === 'granted');
    })();
  }, []);


  const takePicture = async () => {
    if (camera) {
      const data = await camera.takePictureAsync(null)
      console.log('data.uri===========',data.uri)
      setImage(data.uri);
      
      const metadata = {
        contentType: 'image/jpeg',
      }

      const storage = getStorage();
      const storageRef = ref(storage, 'images/mountains.jpg');

      uploadBytes(storageRef, data.uri, metadata).then((snapshot) => {
        console.log('Uploaded a blob or file!');
      });
      
    }
  }



  const _handlePhotoBtnPress = async () => {
    // image library 접근에 대한 허가 필요 없음
    // ImagePicker를 이용해 Image형식의 파일을 가져온다
    let result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.Images,
      allowsEditing: true,
      aspect: [1, 1],
      quality: 1,
    });
 
    console.log(result)

    // cancelled가 아닐 때 가져온 사진의 주소로 onChangePhoto
    if (!result.canceled) {
      console.log(result.uri)
      setImage(result.uri);



      const metadata = {
        contentType: 'image/jpeg',
      }

      uploadBytes(storageRef, result.uri, metadata).then((snapshot) => {
        console.log('Uploaded a blob or file!');
      });
    }
  };



  if (hasCameraPermission === false) {
    return <Text>No access to camera</Text>;
  }



  return (
    <View style={{ flex: 1, padding:30 }}>
      <View style={styles.cameraContainer}>
        <Camera
          ref={ref => setCamera(ref)}
          style={styles.fixedRatio}
          type={type}
          ratio={'1:1'} />
      </View>
      <Button
        title="Flip Image"
        onPress={() => {
          setType(
            type === Camera.Constants.Type.back
              ? Camera.Constants.Type.front
              : Camera.Constants.Type.back
          );
        }}>
      </Button>
      <Button title="Take Picture" onPress={() => takePicture()} />
      <Button title='앨범' onPress={_handlePhotoBtnPress} />

        {image && <Image source={{ uri: image }} style={{ flex:1 }} />}

  
    </View>
  );
}
const styles = StyleSheet.create({
  cameraContainer: {
    flex: 1,
    flexDirection: 'row'
  },
  fixedRatio: {
    flex: 1,
    aspectRatio: 1
  }
})

 

ImagePicker 추가한 것... 일단 뒤죽박죽일거임

import React, { useState, useEffect } from 'react';
import { StyleSheet, Text, View, Button, Image, ScrollView } from 'react-native';
import { Camera } from 'expo-camera';
import * as ImagePicker from 'expo-image-picker';



// firestorage
import { getStorage, ref, uploadBytes, getDownloadURL } from "firebase/storage";


export default function Play(navigation) {
  const [hasCameraPermission, setHasCameraPermission] = useState(null);
  const [camera, setCamera] = useState(null);
  const [image, setImage] = useState(null);
  const [type, setType] = useState(Camera.Constants.Type.back);



  useEffect(() => {
    (async () => {
      const cameraStatus = await Camera.requestCameraPermissionsAsync();
      setHasCameraPermission(cameraStatus.status === 'granted');
    })();
  }, []);


  const takePicture = async () => {
    if (camera) {
      const data = await camera.takePictureAsync(null)
      console.log('data.uri===========',data.uri)
      setImage(data.uri);
      
      const metadata = {
        contentType: 'image/jpeg',
      }


      uploadBytes(storageRef, data.uri, metadata).then((snapshot) => {
        console.log('Uploaded a blob or file!');
      });
      
    }
  }



  const _handlePhotoBtnPress = async () => {
    // image library 접근에 대한 허가 필요 없음
    // ImagePicker를 이용해 Image형식의 파일을 가져온다
    let result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.Images,
      allowsEditing: true,
      aspect: [1, 1],
      quality: 1,
    });
 
    console.log(result)

    // cancelled가 아닐 때 가져온 사진의 주소로 onChangePhoto
    if (!result.canceled) {
      console.log(result.uri)
      setImage(result.uri);



      const metadata = {
        contentType: 'image/jpeg',
      }

      uploadBytes(storageRef, result.uri, metadata).then((snapshot) => {
        console.log('Uploaded a blob or file!');
      });
    }
  };

  const uploadImage = async () => {
    const { uri } = image;
    const filename = uri.substring(uri.lastIndexOf('/') + 1);
    const uploadUri = Platform.OS === 'ios' ? uri.replace('file://', '') : uri;
    setUploading(true);
    setTransferred(0);
    const task = storage()
      .ref(filename)
      .putFile(uploadUri);
    // set progress state
    task.on('state_changed', snapshot => {
      setTransferred(
        Math.round(snapshot.bytesTransferred / snapshot.totalBytes) * 10000
      );
    });

    try {
      await task;
    } catch (e) {
      console.error(e);
    }

    setUploading(false);
    Alert.alert(
      'Photo uploaded!',
      'Your photo has been uploaded to Firebase Cloud Storage!'
    );
    setImage(null);
  };


  if (hasCameraPermission === false) {
    return <Text>No access to camera</Text>;
  }

  const downloadPhoto = async () => {
    console.log(image)

    getDownloadURL(ref(storage, 'img/check.png'))
      .then((url) => {
        // `url` is the download URL for 'images/stars.jpg'
        console.log('getDownload',uri)

        // This can be downloaded directly:
        const xhr = new XMLHttpRequest();
        xhr.responseType = 'blob';
        xhr.onload = (event) => {
          const blob = xhr.response;
        };
        xhr.open('GET', url);
        xhr.send();

        // Or inserted into an <img> element
        const img = document.getElementById('myimg');
        img.setAttribute('src', url);
        console.log(url)
      })
      .catch((error) => {
        console.log('getDownloadURL error',error)
        // Handle any errors
      });

  }


  return (
    <View style={{ flex: 1, padding:30 }}>
      <View style={styles.cameraContainer}>
        <Camera
          ref={ref => setCamera(ref)}
          style={styles.fixedRatio}
          type={type}
          ratio={'1:1'} />
      </View>
      <Button
        title="Flip Image"
        onPress={() => {
          setType(
            type === Camera.Constants.Type.back
              ? Camera.Constants.Type.front
              : Camera.Constants.Type.back
          );
        }}>
      </Button>
      <Button title="Take Picture" onPress={() => takePicture()} />
      <Button title='앨범' onPress={_handlePhotoBtnPress} />
      <Button title='이미지 가져오기' onPress={downloadPhoto} />

        {image && <Image source={{ uri: image }} style={{ flex:1 }} />}

  
    </View>
  );
}
const styles = StyleSheet.create({
  cameraContainer: {
    flex: 1,
    flexDirection: 'row'
  },
  fixedRatio: {
    flex: 1,
    aspectRatio: 1
  }
})

 

최종 코드!!!!!

이미지 피커와 사진을 직접 찍어서 올리는 코드 모두 있다

 

import React, { useState, useEffect } from 'react';
import { StyleSheet, Text, View, Button, Image, ScrollView } from 'react-native';
import { Camera } from 'expo-camera';
import * as ImagePicker from 'expo-image-picker';



// firestorage
import { getStorage, ref, uploadBytes, getDownloadURL } from "firebase/storage";


export default function Play(navigation) {
  const [hasCameraPermission, setHasCameraPermission] = useState(null);
  const [camera, setCamera] = useState(null);
  const [image, setImage] = useState(null);
  const [type, setType] = useState(Camera.Constants.Type.back);
  const [firebaseImage, setFirebaseImage] = useState(null);


  useEffect(() => {
    (async () => {
      console.log('CameraCheck useEffect') 
      const cameraStatus = await Camera.requestCameraPermissionsAsync(); // 카메라 접근 허가
      setHasCameraPermission(cameraStatus.status === 'granted');
    })();
  }, []);


  const takePicture = async () => {
    if (camera) {
      const data = await camera.takePictureAsync(null)
      console.log('data.uri===========',data.uri)
      setImage(data.uri);
      
      const storage = getStorage();
      const storageRef = ref(storage, 'images/check3.jpg');

      const responce = await fetch(image);
      const blob = await responce.blob();

      const response = await uploadBytes(storageRef, blob, {
          contentType: 'image/jpeg',
      });

      const imageset = await getDownloadURL(storageRef)
      console.log(imageset)
      
    }
  }



  const _handlePhotoBtnPress = async () => {
    
    // image library 접근에 대한 허가 필요 없음
    // ImagePicker를 이용해 Image형식의 파일을 가져온다
    let result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.Images,
      allowsEditing: true,
      aspect: [1, 1],
      quality: 1,
    });
 
    console.log('ImagePicker result', result)

    // cancelled가 아닐 때 가져온 사진의 주소로 onChangePhoto
    if (!result.canceled) {
      console.log('result.uri------> ', result.assets[0].uri)
      setImage(result.assets[0].uri);

      const storage = getStorage(); // firebase storage 가져오기
      const storageRef = ref(storage, 'images/checkImagePicker.jpg'); // storage에 저장할 위치 지정 (이미지 이름)

      const responce = await fetch(result.assets[0].uri); // file 형태나 blob 형태로 가져올 수 있음
      const blob = await responce.blob(); // blob 형태로 가져오기

      const response = await uploadBytes(storageRef, blob, {
          contentType: 'image/jpeg',
      }); // storage에 저장하기, content type은 이미지 형식으로 지정

      const imageset = await getDownloadURL(storageRef) // storage에 저장된 이미지의 url 가져오기
      setFirebaseImage(imageset)
      console.log(imageset)
    }
  };



  if (hasCameraPermission === false) {
    return <Text>No access to camera</Text>;
  }



  return (
    <View style={{ flex: 1, padding:30 }}>
      <View style={styles.cameraContainer}>
        <Camera
          ref={ref => setCamera(ref)}
          style={styles.fixedRatio}
          type={type}
          ratio={'1:1'} />
      </View>
      <Button
        title="Flip Image"
        onPress={() => {
          setType(
            type === Camera.Constants.Type.back
              ? Camera.Constants.Type.front
              : Camera.Constants.Type.back
          );
        }}>
      </Button>
      <Button title="Take Picture" onPress={() => takePicture()} />
      <Button title='앨범' onPress={_handlePhotoBtnPress} />

        {image && <Image source={{ uri: firebaseImage }} style={{ flex:1 }} />}

  
    </View>
  );
}
const styles = StyleSheet.create({
  cameraContainer: {
    flex: 1,
    flexDirection: 'row'
  },
  fixedRatio: {
    flex: 1,
    aspectRatio: 1
  }
})

 

 

반응형