简体   繁体   中英

React Native: Photo Won't Upload to Firebase?

I am creating a react Native IOS app and have mostly followed this tutorial with a few changes. The app should function by picking an image from your library, the image is displayed, you press upload image and the progress bar tracks upload progress which when completed will give you an alert that the photo has been uploaded to firebase.

I have managed to get to the point where all explained above is working as it should, except after checking if the photo has been uploaded... it hasn't.

This is my file setup:

在此处输入图像描述

This is my UploadScreen.js file:

import * as React from 'react';
import {useState} from 'react';
import {
  View,
  SafeAreaView,
  Text,
  TouchableOpacity,
  StyleSheet,
  Platform,
  Alert,
  Image,
} from 'react-native';
import * as ImagePicker from 'react-native-image-picker';
import storage from '@react-native-firebase/storage';
import * as Progress from 'react-native-progress';
import {firebase} from '@react-native-firebase/storage';

export default function UploadScreen() {
  const [image, setImage] = useState('');
  const [uploading, setUploading] = useState(false);
  const [transferred, setTransferred] = useState(0);

  const selectImage = () => {
    const options = {
      maxWidth: 2000,
      maxHeight: 2000,
      storageOptions: {
        skipBackup: true,
        path: 'images',
      },
    };
    ImagePicker.launchImageLibrary(options, response => {
      if (response.didCancel) {
        console.log('User cancelled image picker');
      } else if (response.error) {
        console.log('ImagePicker Error: ', response.error);
      } else if (response.customButton) {
        console.log('User tapped custom button: ', response.customButton);
      } else {
        const source = {uri: response?.uri};
        console.log(source);
        setImage(source);
      }
    });
  };

  const uploadImage = async () => {
    const {uri} = image;
    let task; // 👈 Add this
    if (uri) {
      const filename = uri.substring(uri.lastIndexOf('/') + 1);
      const uploadUri =
        Platform.OS === 'ios' ? uri.replace('file://', '') : uri;
      setUploading(true);
      setTransferred(0);
      task = storage().ref(filename).putFile(uploadUri); // 👈 Remove const here
      // 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('');
  };

  return (
    <SafeAreaView style={styles.container}>
      <TouchableOpacity style={styles.selectButton} onPress={selectImage}>
        <Text style={styles.buttonText}>Pick an image</Text>
      </TouchableOpacity>
      <View style={styles.imageContainer}>
        {image !== '' && image !== undefined && (
          <Image source={{uri: image?.uri}} style={styles.imageBox} />
        )}
        {uploading ? (
          <View style={styles.progressBarContainer}>
            <Progress.Bar progress={transferred} width={300} />
          </View>
        ) : (
          <TouchableOpacity style={styles.uploadButton} onPress={uploadImage}>
            <Text style={styles.buttonText}>Upload image</Text>
          </TouchableOpacity>
        )}
      </View>
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    backgroundColor: '#bbded6',
  },
  selectButton: {
    borderRadius: 5,
    width: 150,
    height: 50,
    backgroundColor: '#8ac6d1',
    alignItems: 'center',
    justifyContent: 'center',
  },
  selectButton2: {
    borderRadius: 5,
    width: 150,
    height: 50,
    backgroundColor: '#8ac6d1',
    alignItems: 'center',
    justifyContent: 'center',
    marginTop: 20,
  },
  uploadButton: {
    borderRadius: 5,
    width: 150,
    height: 50,
    backgroundColor: '#ffb6b9',
    alignItems: 'center',
    justifyContent: 'center',
    marginTop: 20,
  },
  buttonText: {
    color: 'white',
    fontSize: 18,
    fontWeight: 'bold',
  },
  imageContainer: {
    marginTop: 30,
    marginBottom: 50,
    alignItems: 'center',
  },
  progressBarContainer: {
    marginTop: 20,
  },
  imageBox: {
    width: 300,
    height: 300,
  },
});

When I run the app on my phone using Xcode this is the output from Metro in the terminal: 地铁输出

And this is 'All Output' from Xcode:

2021-08-04 00:24:21.254981+0100 uploadStorageDemo[16867:5487225] 8.4.0 - [Firebase/Core][I-COR000003] The default Firebase app has not yet been configured. Add `FirebaseApp.configure()` to your application initialization. This can be done in in the App Delegate's application(_:didFinishLaunchingWithOptions:)` (or the `@main` struct's initializer in SwiftUI). Read more: https://firebase.google.com/docs/ios/setup#initialize_firebase_in_your_app.
flipper: FlipperClient::addPlugin Inspector
flipper: FlipperClient::addPlugin Preferences
flipper: FlipperClient::addPlugin React
flipper: FlipperClient::addPlugin Network
2021-08-04 00:24:22.045534+0100 uploadStorageDemo[16867:5487224] [connection] nw_endpoint_handler_set_adaptive_read_handler [C1 192.168.0.31:8081 ready channel-flow (satisfied (Path is satisfied), viable, interface: en0, ipv4, dns)] unregister notification for read_timeout failed
2021-08-04 00:24:22.045575+0100 uploadStorageDemo[16867:5487224] [connection] nw_endpoint_handler_set_adaptive_write_handler [C1 192.168.0.31:8081 ready channel-flow (satisfied (Path is satisfied), viable, interface: en0, ipv4, dns)] unregister notification for write_timeout failed
2021-08-04 00:24:22.064443+0100 uploadStorageDemo[16867:5487072] [native] Running application uploadStorageDemo ({
    initialProps =     {
    };
    rootTag = 1;
})
2021-08-04 00:24:22.075292+0100 uploadStorageDemo[16867:5487227] [connection] nw_endpoint_handler_set_adaptive_read_handler [C2 192.168.0.31:8081 ready channel-flow (satisfied (Path is satisfied), viable, interface: en0, ipv4, dns)] unregister notification for read_timeout failed
2021-08-04 00:24:22.075324+0100 uploadStorageDemo[16867:5487227] [connection] nw_endpoint_handler_set_adaptive_write_handler [C2 192.168.0.31:8081 ready channel-flow (satisfied (Path is satisfied), viable, interface: en0, ipv4, dns)] unregister notification for write_timeout failed
2021-08-04 00:24:22.162117+0100 uploadStorageDemo[16867:5487223] [connection] nw_endpoint_handler_set_adaptive_read_handler [C3 192.168.0.31:8081 ready socket-flow (satisfied (Path is satisfied), viable, interface: en0, ipv4, dns)] unregister notification for read_timeout failed
2021-08-04 00:24:22.162165+0100 uploadStorageDemo[16867:5487223] [connection] nw_endpoint_handler_set_adaptive_write_handler [C3 192.168.0.31:8081 ready socket-flow (satisfied (Path is satisfied), viable, interface: en0, ipv4, dns)] unregister notification for write_timeout failed
2021-08-04 00:24:22.162328+0100 uploadStorageDemo[16867:5487223] [connection] nw_endpoint_handler_set_adaptive_read_handler [C4 192.168.0.31:8081 ready socket-flow (satisfied (Path is satisfied), viable, interface: en0, ipv4, dns)] unregister notification for read_timeout failed
2021-08-04 00:24:22.162448+0100 uploadStorageDemo[16867:5487223] [connection] nw_endpoint_handler_set_adaptive_write_handler [C4 192.168.0.31:8081 ready socket-flow (satisfied (Path is satisfied), viable, interface: en0, ipv4, dns)] unregister notification for write_timeout failed
2021-08-04 00:24:22.621103+0100 uploadStorageDemo[16867:5487237] [javascript] Running "uploadStorageDemo" with {"rootTag":1,"initialProps":{}}
2021-08-04 00:24:22.629095+0100 uploadStorageDemo[16867:5487227] [connection] nw_socket_handle_socket_event [C5:1] Socket SO_ERROR [61: Connection refused]
2021-08-04 00:24:22.629688+0100 uploadStorageDemo[16867:5487228] [connection] nw_connection_get_connected_socket [C5] Client called nw_connection_get_connected_socket on unconnected nw_connection
2021-08-04 00:24:22.629720+0100 uploadStorageDemo[16867:5487228] TCP Conn 0x281478dc0 Failed : error 0:61 [61]
2021-08-04 00:24:22.652804+0100 uploadStorageDemo[16867:5487228] [connection] nw_endpoint_handler_set_adaptive_read_handler [C6 192.168.0.31:8081 ready socket-flow (satisfied (Path is satisfied), viable, interface: en0, ipv4, dns)] unregister notification for read_timeout failed
2021-08-04 00:24:22.652836+0100 uploadStorageDemo[16867:5487228] [connection] nw_endpoint_handler_set_adaptive_write_handler [C6 192.168.0.31:8081 ready socket-flow (satisfied (Path is satisfied), viable, interface: en0, ipv4, dns)] unregister notification for write_timeout failed
2021-08-04 00:24:43.124938+0100 uploadStorageDemo[16867:5487225] [default] [ERROR] Could not create a bookmark: NSError: Cocoa 257 "The file couldn’t be opened because you don’t have permission to view it." }
2021-08-04 00:24:43.507605+0100 uploadStorageDemo[16867:5487237] [javascript] { uri: 'file:///var/mobile/Containers/Data/Application/3E0DE5DE-38BA-43C2-B63D-B937EC1175D3/tmp/8C4CF4D2-51DF-4064-A754-21979A6167CD.jpg' }
2021-08-04 00:24:46.603236+0100 uploadStorageDemo[16867:5487224] Setting emulator - host (null) port 0
2021-08-04 00:24:46.701265+0100 uploadStorageDemo[16867:5487224] [connection] nw_endpoint_handler_set_adaptive_read_handler [C7.1 216.58.213.10:443 ready channel-flow (satisfied (Path is satisfied), viable, interface: en0, ipv4, dns)] unregister notification for read_timeout failed
2021-08-04 00:24:46.701300+0100 uploadStorageDemo[16867:5487224] [connection] nw_endpoint_handler_set_adaptive_write_handler [C7.1 216.58.213.10:443 ready channel-flow (satisfied (Path is satisfied), viable, interface: en0, ipv4, dns)] unregister notification for write_timeout failed
2021-08-04 00:24:48.329172+0100 uploadStorageDemo[16867:5487224] BackgroundSession <4A4B90EE-3A20-412D-9888-93329B680CB9> connection to background transfer daemon invalidated

I have noticed the first line of this mentions that Firebase isn't configured however I have added the 'GoogleService-Info.plist' to the project using Xcode and the Bundle Identifier names match so I'm not sure what else I've missed out... (followed the tutorial linked at the beginning).

Finally, these are my Firebase Storage rules: Firebase 存储规则

I am fairly new to React Native and have never used firebase before other than with this project so slightly lost as to what's going wrong... any help would be appreciated. Thank you.

PS I am more than happy to provide any more information if it's necessary just let me know what:)

All I'll say is make sure you're checking the correct database xD

I had this same problem with this same function and I was trying to solve it for days.

To solve this I configured the anonymous login in firebase, installed the package and imported @react-native-firebase/auth, then in.putFile() I passed the uri without any changes.

It's working perfectly on the iPhone APP.

Would be like this:

    import auth from '@react-native-firebase/auth';


    const uploadImage = async () => {
     await auth()
      .signInAnonymously()
      .then(() => {
        setLoading(true);
        console.log('user logged in anonymously.');
      })
      .catch((error) => {
        if (error.code === 'auth/operation-not-allowed') {
          console.log('Enable anonymous in your firebase console.');
        }

        console.error(error);
      });

    const {uri} = image;

    let task;

    if (uri) {
      const filename = uri.substring(uri.lastIndexOf('/') + 1);
      const uploadUri = uri;
      setUploading(true);
      setTransferred(0);
      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('');
  };

Forgive my English. I am Brazilian and I am not fluent in English.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM