如何在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
相关产品推荐
相关产品推荐

