ReactNative (Expo)로 Firebase Storage에 이미지를 업로드하는 방법

소개



Expo에서 Firebase를 사용하는 경우 웹 버전의 Firebase를 사용하게 될 것입니다. 여기서 FirebaseStorage에 이미지를 업로드할 때 몇 가지 함정이 있었고, 필자는 이틀 이상 녹아 버렸습니다. 구체적으로는 다음과 같은 함정이있었습니다.
  • reactnative가 atob 함수를 지원하지 않기 때문에 저장소를 사용할 수 없습니다
  • storage에 base64 인코딩 이미지를 업로드했지만 잘 표시되지 않습니다

  • 이상의 2점에 대해서, 구체적으로 설명해 갑니다.

    1. ImageForm 만들기


    class ImageForm extends React.Component {
        constructor(props) {
            super(props)
    }
    
        componentDidMount() {
            this.getPermissionAsync();
          }
    
        getPermissionAsync = async () => {
            if (Constants.platform.ios) {
              const { status } = await Permissions.askAsync(Permissions.CAMERA_ROLL);
              if (status !== 'granted') {
                alert('Sorry, we need camera roll permissions to make this work!');
              }
            }
          }
    
          _pickImage = async () => {
            let result = await ImagePicker.launchImageLibraryAsync({
              mediaTypes: ImagePicker.MediaTypeOptions.All,
              allowsEditing: true,
              aspect: [4, 3],
              base64: true,
              quality: 0.5
            });
    
            console.log(result);
    
            if (!result.cancelled) {
                var uris = this.props.uris
                const uri = result.uri
                uris.push(uri)
           // 
            }
          };
    
    
          render() {
    
            return (
              <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
              <Text >{this.props.title}</Text>
                <Button
                  title="Pick an image from camera roll"
                  onPress={this._pickImage}
                />
    
              </View>
            );
          }
        }
    

    iphone에서 사용할 수 있도록 getPermissionAsync를해야합니다.
    Button을 누르면 이미지를 Pick 할 수 있으며 URL을 URL에 저장합니다.
    이 URL을 props 등에 저장하십시오.

    2. firebase storage로 이미지 업데이트



    저자는 redux-saga와 redux-saga-firebase를 사용하여 비동기 처리를 수행하고 있습니다. 흐름으로서는, pick했을 때의 화상 uri로부터 화상 ​​데이터를 fetch 해 blob 데이터를 취득. 그것을 업로드합니다.
    function fetchImage(fileData){
        return fetch(fileData)
        .then(results => {
            const blob = results._bodyBlob;
            return blob
        })
        .catch(error => {
            console.log("error" , error)
        })
    }
    
    export function* uploadImageToStorage({uris}){ 
        var filePath = "/image300"
        const uri = uris[0]
        const blob = yield call(fetchImage, uri)
        const metadata = {contentType: "image/jpeg"}
        yield call(storage.uploadFile, filePath, blob, metadata)
    

    이상의 소스 코드를 saga 내에 넣는 것으로 할 수 있게 됩니다.


    발생하는 함정, 오류



    atob 함수에 해당하지 않음



    [base-64] 라이브러리를 설치하고 node-module에 직접 씁니다.
    npm install -s base-64
    

    /node-modules/redux-saga-firebase/storage.js
    ~~~
    const atob = require('base-64').decode;
    window.atob = atob;
    ~~~

    putString이나 uploadString으로 base64를 직접 업로드했지만 base64와 형식이 다르거나 미리보기가 표시되지 않습니다.



    여기서 꽤 시간을 잡았습니다. 제일의 대응책은 base64를 직접 업로드하는 것이 아니라, Blob형으로 해 업로드하는 것이라고 생각합니다. 위의 방법으로 할 수 있다고 생각하기 때문에 해보십시오.

    참고 URL

    좋은 웹페이지 즐겨찾기