使用Hermes引擎时expo-image-picker报错及Firestore图片URI存为null求助
解决Expo ImagePicker + Hermes模块找不到及图片URI存Firestore问题
一、先修复「Cannot find native module 'ExponentImagePicker'」错误
该错误源于Expo 44版本中Hermes引擎与expo-image-picker的缓存/版本兼容问题,按以下步骤处理:
- 确保依赖版本匹配
使用Expo官方安装命令,保证模块版本与Expo SDK 44完全兼容:
expo install expo-image-picker
- 清除缓存重启项目
缓存残留会导致模块识别异常,执行:
expo r -c
- 确认导入方式正确
自定义ImagePicker组件中,必须使用官方正确的导入路径:
import * as ImagePicker from 'expo-image-picker';
- 检查Hermes配置(可选)
若项目明确启用Hermes,确保app.json配置正确:
{ "expo": { "jsEngine": "hermes" } }
二、实现图片URI传递与Firestore存储
当前PlaceForm与ImagePicker组件无数据交互,导致图片URI无法传递到父组件提交到Firestore,按以下步骤修改:
1. 修改PlaceForm组件,添加图片状态与提交逻辑
import { useState } from "react"; import { ScrollView, StyleSheet, Text, TextInput, View, Button, Alert } from "react-native"; import { Colors } from "../../constants/colors"; import ImagePicker from "./ImagePicker"; import firestore from '@react-native-firebase/firestore'; function PlaceForm(){ const [enteredTitle, setEnteredTitle] = useState(''); const [selectedImageUri, setSelectedImageUri] = useState(null); // 新增图片URI状态 function changeTitleHandler(enteredText){ setEnteredTitle(enteredText); } // 新增Firestore提交函数 const submitToFirestore = async () => { if (!enteredTitle.trim() || !selectedImageUri) { Alert.alert('提示', '请填写标题并选择图片'); return; } try { await firestore().collection('places').add({ title: enteredTitle, imageUri: selectedImageUri, createdAt: firestore.FieldValue.serverTimestamp() }); // 重置表单 setEnteredTitle(''); setSelectedImageUri(null); Alert.alert('成功', '数据已保存到Firestore'); } catch (err) { console.error('保存失败:', err); Alert.alert('错误', '保存数据失败,请重试'); } }; return( <ScrollView style={styles.form}> <View> <Text style={styles.label}>Title</Text> <TextInput style={styles.input} onChangeText={changeTitleHandler} value={enteredTitle}/> </View> {/* 传递回调接收图片URI */} <ImagePicker onImageSelect={setSelectedImageUri} /> {/* 添加提交按钮 */} <Button title="提交" onPress={submitToFirestore} style={{marginTop: 16}} /> </ScrollView> ) } export default PlaceForm; const styles = StyleSheet.create({ form :{ flex: 1, padding:24, }, label:{ fontWeight:'bold', marginBottom:4, color: Colors.primary500 }, input:{ marginBottom:8, paddingHorizontal:4, paddingVertical:8, fontSize:16, borderBottomColor:Colors.primary700, borderBottomWidth:2, backgroundColor: Colors.primary100 } })
2. 完善ImagePicker组件,实现图片选择与回调传递
import { useState } from 'react'; import { Button, View, Image, StyleSheet, Alert } from 'react-native'; import * as ImagePicker from 'expo-image-picker'; export default function ImagePicker({ onImageSelect }) { const [localImageUri, setLocalImageUri] = useState(null); // 申请相册权限 const requestPermission = async () => { const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync(); if (status !== 'granted') { Alert.alert('权限不足', '需要允许访问相册才能选择图片'); return false; } return true; }; // 图片选择逻辑 const pickImage = async () => { const hasPermission = await requestPermission(); if (!hasPermission) return; const result = await ImagePicker.launchImageLibraryAsync({ mediaTypes: ImagePicker.MediaTypeOptions.Images, allowsEditing: true, aspect: [4, 3], quality: 0.7, }); // Expo 44返回结构为assets数组,取第一个元素的uri if (!result.canceled) { const imageUri = result.assets[0].uri; setLocalImageUri(imageUri); onImageSelect(imageUri); // 传递URI给父组件 } }; return ( <View style={styles.container}> <Button title="选择图片" onPress={pickImage} /> {/* 预览选中图片 */} {localImageUri && ( <Image source={{ uri: localImageUri }} style={styles.previewImage} /> )} </View> ); } const styles = StyleSheet.create({ container: { marginVertical: 16, alignItems: 'center', }, previewImage: { width: 200, height: 150, marginTop: 12, borderRadius: 8, backgroundColor: '#f0f0f0', }, });
三、验证流程
- 重启项目后,点击「选择图片」,确认权限申请正常,能选择并预览图片
- 填写标题后点击「提交」,检查Firestore的
places集合中是否存在包含imageUri字段的文档
内容的提问来源于stack exchange,提问作者Ravi Mishra
相关产品推荐
相关产品推荐

