上传 base64 图片到 Firebase React native

Upload base64 Image to Firebase React native

我尝试在 iOS 上使用 React Native 将“base64”图像上传到 Firebase。但是当我尝试上传图片时,出现以下错误:

undefined is not an object (evaluating 'uri.substring')

我使用 route.params 获取图像,如果我在这样的视图中显示图像,就会显示图像。

<Image style={styles.image} source={{ uri: `data:image/png;base64,${myImage}` }}/>

如果图像是“base64”,我还应该做些什么吗?或者我还应该做什么?

这是我的代码:

// Here is how I get the image
const { myImage } = props.route.params;

const uploadImage = async () => {
  const {uri} = myImage;
  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!'
  );
};

看你现在的代码,你从props.route.params中取出myImage,这是一串对应PNG图片的Base 64字符(比如iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAMSURBVBhXY/j//z8ABf4C/qc1gYQAAAAASUVORK5CYII= -单个 #FFFFFF 像素的 PNG 数据)。

const { myImage } = props.route.params;

下面你尝试从这个 myImage 字符串中得到一个 属性 uri。由于此 属性 不存在,您将得到 undefined。然后,此 uri = undefined 值会在下一行引发错误。

const { uri } = myImage; // uri is undefined! ("".uri === undefined)
const filename = uri.substring(uri.lastIndexOf('/') + 1); // throws error!

上传数据 URL 的正确方法是使用 Reference#putString() method as covered in the documentation here

将此应用于您的代码,您将使用:

const { myImage } = props.route.params;

const uploadImage = async () => {
  const dataUrl = `data:image/png;base64,${myImage}`;

  // you could use a Firestore Doc ID, a RTDB Push ID or
  // some `uuid` implementation to generate a suitable filename.
  const storageRef = storage()
    .ref(/* provide a path for the image */);

  const uploadTask = storageRef
    .putString(dataUrl, 'data_url');

  uploadTask.on('state_changed', snapshot => {
    setTransferred(
      Math.round(snapshot.bytesTransferred / snapshot.totalBytes) * 10000
    );
  });

  try {
    await uploadTask;
    
    setUploading(false);
    Alert.alert(
      'Photo uploaded!',
      'Your photo has been uploaded to Firebase Cloud Storage!'
    );
  } catch (err) {
    // TODO: Check value of `err.code` and handle appropriately.
    console.error('Upload failed: ', err);
    Alert.alert(
      'Photo upload failed!',
      'Your photo didn\'t upload properly!'
    );
  }
}

为防止覆盖其他人的数据并使安全规则更易于实施,您应该在上传的文件前加上用户 ID,类似于:

const storageRef = storage()
    .ref('userUploads')
    .child(firebase.auth().currentUser.uid)
    .child(/* generated image ID */);

// builds a reference to /userUploads/someUserId/someImageId

如果您的图像数据字符串如下所示: data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABQAAAALQCAYAAADPfd1WAAAAAXNSR0IArs4c6QAAIABJREFUeF7svXmPLEly4GcRkVnnO/r1656+5uRcJEGAnMEO ...

然后你可以使用putString方法 - 但你需要先删除起始信息data:image/png;base64,

await storage.ref("pictures/thumbnail.png").putString(thumbnailImageData.split("data:image/png;base64,")[1], "base64");