You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在React Native Expo中使用Firebase v9上传照片至Storage

解决方案

1. 修复firebase.js配置

你的firebase.js中存在两处错误配置,直接导致方法调用异常:

  • 错误地提前执行了ref和uploadBytes方法,这两个是工具函数,无需实例化直接使用即可
  • getStorage需要传入初始化后的app实例,避免运行时找不到storage实例的问题

修复后的完整代码:

// Import the functions you need from the SDKs you need
import {initializeApp } from "firebase/app";
import {getAuth} from 'firebase/auth';
import {getFirestore} from 'firebase/firestore';
import { getStorage, ref, uploadBytes } from 'firebase/storage';
import firebase from 'firebase/compat/app';

// Your web app's Firebase configuration
const firebaseConfig = {
  apiKey: "AIzaSyBLc-5dJjxHSxt1-GLCh0eNKHKN8jnhPLk",
  authDomain: "image-22e99.firebaseapp.com",
  projectId: "image-22e99",
  storageBucket: "image-22e99.appspot.com",
  messagingSenderId: "71958952042",
  appId: "1:71958952042:web:22638e27a52d86d5a73213"
};

// Initialize Firebase
const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
const db = getFirestore(app);
const storage = getStorage(app);

export {db , auth, storage , ref, uploadBytes};
export default firebase;

2. 实现App.js中的上传功能

首先补全react-native的Platform导入,然后实现upload异步函数,Expo返回的本地图片uri需要先转为Blob格式才能传给Firebase上传:

完整的App.js代码如下:

import * as ImagePicker from 'expo-image-picker';
import React, { useEffect, useState } from 'react';
import {
  ActivityIndicator,
  Button,
  Image,
  SafeAreaView,
  StyleSheet,
  Platform, // 补全缺失的导入
  Alert
} from 'react-native';

import { storage ,ref,uploadBytes} from './firebase';


export default function App() {
  const [imageUri, setImageUri] = useState(null);
  const [uploading, setUploading] = useState(false);

  useEffect(() => {
    getPermission();
  }, []);

  const getPermission = async () => {
    if (Platform.OS !== 'web') {
      const { status } =
        await ImagePicker.requestMediaLibraryPermissionsAsync();
      if (status !== 'granted') {
        alert('Sorry, we need camera roll permissions to make this work!');
      }
    }
  };

  const pickImage = async () => {
    let result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.All,
      allowsEditing: true,
      aspect: [4, 3],
      quality: 1,
    });

    console.log(result);

    if (!result.cancelled) {
      setImageUri(result.uri);
    }
  };

  const upload = async () => {
    if (!imageUri) {
      Alert.alert('提示', '请先选择要上传的图片');
      return;
    }
    setUploading(true);
    try {
      // 将本地uri转为Blob
      const response = await fetch(imageUri);
      const blob = await response.blob();
      // 生成存储路径,用时间戳作为文件名避免重复
      const storageRef = ref(storage, `images/${Date.now()}.jpg`);
      // 执行上传
      await uploadBytes(storageRef, blob);
      Alert.alert('提示', '上传成功');
      setImageUri(null);
    } catch (error) {
      console.log('上传失败', error);
      Alert.alert('错误', '上传失败,请稍后重试');
    } finally {
      setUploading(false);
    }
  }

  return (
    <SafeAreaView style={styles.container}>
      <Image source={{ uri: imageUri }} style={{ width: 300, height: 300 }} />
      <Button title='Choose picture' onPress={pickImage} />

      {uploading ? (
        <ActivityIndicator />
      ) : (
        <Button title='Upload' onPress={upload} />
      )}

      
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

核心逻辑说明

Firebase v9采用模块化API设计,废弃了旧版本storage.ref()的链式调用写法,改为单独导入ref函数,传入storage实例和存储路径生成引用,其他Storage相关操作也都遵循同样的模块化调用规则。

内容的提问来源于stack exchange,提问作者user17466327

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 01:15:04