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

Firebase 9更新指定文档时出现Uncaught TypeError错误排查

Firebase 9 更新文档时出现 TypeError: n.indexOf is not a function 问题

错误信息

Uncaught (in promise) TypeError: n.indexOf is not a function
    at rt.fromString (index.esm2017.js:1032:1)
    at sa (index.esm2017.js:16038:1)
    at actions.js:136:1
    at Object.dispatch (index.js:16:1)
    at dispatch (<anonymous>:3665:80)
    at editFeedback (EditFeedbackPage.js:55:1)
    at HTMLUnknownElement.callCallback (react-dom.development.js:4164:1)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:4213:1)
    at invokeGuardedCallback (react-dom.development.js:4277:1)
    at invokeGuardedCallbackAndCatchFirstError (react-dom.development.js:4291:1)

问题情况

  • 资料显示该错误可能是引用数据库中不存在的文档导致。
  • 通过useParams()获取的文档ID,在useEffect()中能正常打印,但传入editFeedback()并在dispatch中使用时变为undefined;尝试将ID存入state后依然是undefined。
  • 添加、删除、获取文档操作均正常,仅更新文档出现问题,且更新逻辑参照了正常工作的删除文档写法。

相关代码

EditFeedbackPage.js

const EditFeedbackPage = () => {

    const initialState = {
        category: "All",
        comments: [],
        detail: "",
        id: nanoid(),
        createdAt: Timestamp.now().toDate(),
        status: "Suggestion",
        title: "",
        upVotesCount: []
    }

    const ref = useRef()
    const [state, setState] = useState(initialState);
    const { feedback } = useSelector((state) => state.data);

    const { category, detail, title, status } = feedback;
    console.log(feedback)

    const params = useParams();
    const { id } = params;
    console.log("id from params => ", id)
    // id from params =>  TexT99K7xz1Q2a4xv5PF

    const dispatch = useDispatch();

    const navigate = useNavigate();

    const cancelAddFeedback = () => {
        navigate("/")
    }

    useEffect(() => {
        dispatch(getSingleFeedback(id));
        console.log("feedbackId => ", id);

    }, []);

    const editFeedback = async (e, id) => {
        e.preventDefault();
        console.log("feedbackId => ", id);
        dispatch(editFeedbackInit(id, feedback))
    }

    const handleInputChange = (e) => {
        let { name, value } = e.target;
        setState({ ...state, [name]: value })
    }

    const handleSubmit = (e) => {
        e.preventDefault();
        setState({ ...state, title: '', detail: "", category: "All" })
    }

    return (
        <EditFeedbackContainer>
            <EditFeedbackWholeContainer>
                <NavbarFeedback />
                <EditFeedbackInnerContainer>
                    <h2>Edit Feedback</h2>
                    <EditFeedbackFormContainer
                        onSubmit={handleSubmit}
                    >
                        <h4>Feedback Title</h4>
                        <label htmlFor="title">Add a short, descriptive headline</label>
                        <input
                            ref={ref}
                            type="text"
                            name='title'
                            defaultValue={title}
                            onChange={handleInputChange}
                        />

            ---------------------
                        <EditFeedbackButtonsContainer>
                            <EditFeedbackButtonDelete
                            // onClick={deleteFeedback}
                            >
                                Delete
                            </EditFeedbackButtonDelete>

                            <EditFeedbackButtonCancel onClick={cancelAddFeedback}>Cancel</EditFeedbackButtonCancel>
                            <EditFeedbackButtonAdd
                                onClick={editFeedback}
                            >Edit Feedback</EditFeedbackButtonAdd>
                        </EditFeedbackButtonsContainer>
                    </EditFeedbackFormContainer>
                </EditFeedbackInnerContainer>
            </EditFeedbackWholeContainer>
        </EditFeedbackContainer >
    )
}

actions.js(更新文档逻辑)

// edit feedbacks actions

const editFeedbackStart = () => ({
    type: types.EDIT_FEEDBACK_START,
});

const editFeedbackSussess = () => ({
    type: types.EDIT_FEEDBACK_SUCCESS,
});

const editFeedbackFail = () => ({
    type: types.EDIT_FEEDBACK_FAIL,
});
    
export const editFeedbackInit = (feedback, id, err) => {
        return async function (dispatch) {
            dispatch(editFeedbackStart());
            console.log(id)

            // await db.collection("feedbacks").doc(id).update(feedback);
            // console.log(id)
            // => also tried this version above

            const feedDoc = doc(db, "feedbacks", id);
            await updateDoc(feedDoc, feedback);
            console.log(id)

            dispatch(editFeedbackSussess());
            if (err) {
                dispatch(editFeedbackFail(err))
            }
        };
    }

正常工作的删除文档逻辑

export const deleteFeedbackInit = (id, err) => {
    return function (dispatch) {
        dispatch(deleteFeedbackStart());

        db.collection("feedbacks").doc(id).delete();
        dispatch(deleteFeedbackSussess());
        if (err) {
            dispatch(deleteFeedbackFail(err))
        }
    };
}

问题根源与解决方案

两个核心错误

  1. 函数参数顺序不匹配

    • editFeedbackInit定义的参数顺序是(feedback, id, err),但在editFeedback中调用时传入的是(id, feedback),导致Firebase收到的id实际是feedback对象。对象没有indexOf方法,因此触发报错。
  2. onClick未传递id参数

    • editFeedback函数定义了(e, id)参数,但<EditFeedbackButtonAdd onClick={editFeedback}>仅传递了事件对象e,id参数未传入,导致editFeedback中的id为undefined。

修正步骤

步骤1:修正参数传递

  • 方法一:修改editFeedback的调用方式,显式传递id
<EditFeedbackButtonAdd
    onClick={(e) => editFeedback(e, id)}
>Edit Feedback</EditFeedbackButtonAdd>
  • 方法二:去掉editFeedback的id参数,直接使用组件内的id变量
const editFeedback = async (e) => {
    e.preventDefault();
    console.log("feedbackId => ", id);
    dispatch(editFeedbackInit(id, feedback))
}

步骤2:统一参数顺序

将actions.js中的editFeedbackInit参数顺序改为(id, feedback, err),与调用顺序一致:

export const editFeedbackInit = (id, feedback, err) => {
        return async function (dispatch) {
            dispatch(editFeedbackStart());
            console.log(id)

            const feedDoc = doc(db, "feedbacks", id);
            await updateDoc(feedDoc, feedback);
            console.log(id)

            dispatch(editFeedbackSussess());
            if (err) {
                dispatch(editFeedbackFail(err))
            }
        };
    }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 09:35:22