首页 > 解决方案 > 函数不返回对象而是未定义

问题描述

我想将我在 Firestore 调用中创建的对象返回到我的 UI 组件。经过大量关于使用异步函数和 .then() 从函数接收数据的研究,我仍然无法让它工作。我只是不确定。我发现的大多数答案都说我应该在处理响应时使用 await 和/或 .then() ,而不是仅仅得到一个承诺。但是我尝试过的任何东西都没有得到一些实际数据。对象始终未定义。

Firebase 配置:

export const getLatestAcceptedSample = async (bottleID, equipmentID) => {
    let msg = {}
    try {
        await db.collection('Oil Samples').orderBy('createdAt', 'desc').limit(1).get().then(querySnapshot => {
            querySnapshot.forEach(documentSnapshot => {
                const tempMsg = documentSnapshot.data()

                if (bottleID === tempMsg.bottleID && equipmentID === tempMsg.equipmentID) {
                    msg = {
                        bottleID: tempMsg.bottleID,
                        equipmentID: tempMsg.equipmentID,
                        timestamp: tempMsg.createdAt?.toDate() ?? '',
                        userName: tempMsg.authorName,
                        userID: tempMsg.authorID,
                        title: tempMsg.title
                    }
                    console.log(msg)
                    return msg

                } else {
                    alert("Fetching data from database failed")
                }
                return msg

            })

        })

    }
    catch {
        alert('Get Latest Sample error')
    }
}

调用该函数的 UI 组件:

export default function SampleAcceptedScreen(props) {

    const { bottleID, equipmentID } = props.route.params
    const [docBottleID, setDocBottleID] = useState('')
    const [docEquipmentID, setDocEquipmentID] = useState('')
    const [userName, setUserName] = useState('')


    useEffect(() => {
        try {
            FirestoreService.getLatestAcceptedSample(bottleID, equipmentID).then((msg) => {
                console.log(msg)
                setDocBottleID(msg.bottleID)
                setDocEquipmentID(msg.equipmentID)
                setUserName(msg.userName)
            })
        }
        catch {
            console.log(error)
        }
    })

    return (
        <View style={styles.container} >
            <CustomHeader title="Sample Accepted" navigation={props.navigation} isHome={false} />
            <View style={styles.contentContainer} >
                <Text style={styles.header} >Oil sample has been registered!</Text>
                <Text style={styles.header2} >The following details have been associated with the sampling:</Text>
                <Text>User: {userName} </Text>
                <Text>Bottle barcode: {docBottleID} </Text>
                <Text>Equipment barcode: {docEquipmentID} </Text>
                <TouchableOpacity style={styles.button}
                    onPress={() =>
                        props.navigation.dispatch(
                            CommonActions.reset({
                                index: 1,
                                routes: [
                                    { name: 'HomeScreen' },
                                    {
                                        name: 'HomeScreen',
                                        params: { bottleID: undefined, equipmentID: undefined }
                                    }
                                ]
                            })
                        )} >
                    <Text style={styles.buttonText} >Accept</Text>
                </TouchableOpacity>
            </View>
        </View>
    );
}

标签: javascriptfirebasereact-nativegoogle-cloud-firestoreasync-await

解决方案


我解决了这个问题。我把它移到了return msg这里:

  export const getLatestAcceptedSample = async (bottleID, equipmentID) => {
    let msg = {}
    try {
        await db.collection('Oil Samples').orderBy('createdAt', 'desc').limit(1).get().then(querySnapshot => {
            querySnapshot.forEach(documentSnapshot => {
                const tempMsg = documentSnapshot.data()
                if (bottleID === tempMsg.bottleID && equipmentID === tempMsg.equipmentID) {
                    msg = {
                        bottleID: tempMsg.bottleID,
                        equipmentID: tempMsg.equipmentID,
                        timestamp: tempMsg.createdAt?.toDate() ?? '',
                        userName: tempMsg.authorName,
                        userID: tempMsg.authorID,
                        title: tempMsg.title
                    }
                    console.log(msg)
                } else {
                    alert("Fetching data from database failed")
                }
            })
        })
        return msg
    }
    catch {
        alert('Get Latest Sample error')
    }
}

显然我写的逻辑大部分是正确的,但返回的范围不正确。


推荐阅读