Expo项目移动端Firebase addDoc()报错:字段值undefined求助
Expo React Native 表单数据写入Firebase报错:Unsupported field value: undefined
问题描述
网页版可正常将联系表单数据写入Firebase数据库,但移动端提交时触发报错:
FirebaseError: Function addDoc() called with invalid data. Unsupported field value: undefined (found in field title in document posts/5TT9b7F0lkqxoivmsIiH)
问题原因
- React Native与Web端事件机制差异:React Native的
TextInput组件不支持Web端的event.target.value写法,移动端下event.target为undefined,导致name/email/message三个state始终未被正确更新,最终传入addDoc()的是undefined值。 - State未设置初始值:
useState()未指定初始空字符串,初始state为undefined,进一步加剧了数据异常。 - 表单标签错误:三个输入框的提示文本都写的"Name",属于无关但需要修正的小问题。
修复方案
1. 替换TextInput的事件处理方式
将onChange改为React Native专用的onChangeText,直接接收输入值更新state。
2. 给State设置初始空字符串
确保state初始值为'',避免未输入时出现undefined。
3. 修正表单提示文本
将三个输入框的提示分别改为"Name"、"Email"、"Message",提升用户体验。
修改后的完整代码
import React, { useEffect, useState } from "react"; import { View, Text, StyleSheet, SafeAreaView, TextInput, Button } from "react-native"; import { useNavigation } from "@react-navigation/native"; import { FontAwesome } from '@expo/vector-icons'; import colors from '../colors'; import { auth, database } from '../config/firebase'; import { collection, addDoc } from 'firebase/firestore'; const Home = () => { const navigation = useNavigation(); // 给state设置初始空字符串 const [name, setName] = useState(''); const [email, setEmail] = useState(''); const [message, setMessage] = useState(''); const userCollectionRef = collection(database, 'contactdata'); const handleSubmit = () => { addDoc(userCollectionRef, { name: name || null, email: email || null, message: message || null }); } useEffect(() => { navigation.setOptions({ headerLeft: () => ( <FontAwesome name="home" size={25} color={'#1C64D1'} style={{ marginLeft: 15 }} /> ), headerRight: () => ( <FontAwesome name="user" size={24} color={'#1C64D1'} style={{ marginRight: 25 }} /> ), }); }, [navigation]); return ( <View style={styles.container}> <SafeAreaView style={styles.form}> <Text style={styles.heading}>Complaint Form</Text> <Text style={{ marginLeft: 15, marginTop: 20 }}>Name</Text> {/* 改用onChangeText直接接收值 */} <TextInput style={styles.input} onChangeText={setName} /> <Text style={{ marginLeft: 15, marginTop: 20 }}>Email</Text> <TextInput style={styles.input} onChangeText={setEmail} /> <Text style={{ marginLeft: 15, marginTop: 20 }}>Message</Text> <TextInput style={styles.input} onChangeText={setMessage} /> <Button title="Submit" onPress={handleSubmit} color={colors.primary} /> </SafeAreaView> </View> ); }; export default Home; const styles = StyleSheet.create({ container: { backgroundColor: "#fff", flex: 1, // 添加flex:1让容器占满屏幕 flexDirection: "column", }, form: { flex: 1, paddingHorizontal: 10, }, heading: { fontSize: 20, fontWeight: 'bold', textAlign: 'center', marginTop: 20, }, input: { borderWidth: 1, borderColor: '#ccc', borderRadius: 5, padding: 10, marginHorizontal: 15, marginTop: 5, }, });
额外说明
- 补充了
styles.form、styles.heading、styles.input的样式,让表单布局更合理; - 给
container添加了flex:1,确保容器占满整个屏幕; - 将按钮文本改为"Submit",更贴合表单提交的语义。
内容的提问来源于stack exchange,提问作者Hymdal
相关产品推荐
相关产品推荐

