【问题标题】:React with Firebase - submitting Formik form dataReact with Firebase - 提交 Formik 表单数据
【发布时间】:2026-01-21 08:40:01
【问题描述】:

我有一个 react 应用程序,它使用 Formik 作为表单,使用 Cloud Firestore 作为数据库。

我正在尝试将表单数据保存在 Cloud Firestore 中。我的控制台或反应检查器工具中没有错误,当我按下提交时,我可以在反应检查工具中看到按钮变为禁用然后再次启用,但表单不会清除数据并且数据会不会被发送到 Cloud Firestore。

我的 handleSubmit 函数有:

handleSubmit = (formState, { resetForm }) => {
    // Now, you're getting form state here!
    const payload = {
        ...formState,
        fieldOfResearch: formState.fieldOfResearch.map(t => t.value),
        preregisterPlatform: formState.preregisterPlatform.value,
        resourceRequests: formState.resourceRequests.map(t => t.value),
        resourceOffers: formState.resourceOffers.map(t => t.value),
        ethicsIssue: formState.ethicsIssue.map(t => t.value),
        disclosureStatus: formState.disclosureStatus.value,
        createdAt: firebase.firestore.FieldValue.serverTimestamp()
      }
      console.log("formvalues", payload);

    fsDB
      .collection("project")
      .add(payload)
      .then(docRef => {
        console.log("docRef>>>", docRef);
        resetForm(initialValues);
      })
      .catch(error => {
        console.error("Error adding document: ", error);
      });
  };

我的提交按钮有:

<div className="form-group">
                            <Button
                                variant="outline-primary"
                                type="submit"
                                id="ProjectId"
                                onClick={handleSubmit}
                                disabled={!dirty || isSubmitting}
                            >
                                Save
                            </Button>
                        </div>

表格很长 - 它有 39 个问题,从我的 Cloud Firestore 数据使用情况可以看出,我没有接近读写限制。我不知道如何测量我的表单提交数据的大小以了解表单数据是否超过 Cloud Firestore 限制 - 有没有办法让 Firestore 告诉您这是否是提交不起作用的原因?

用于查看 handleSubmit 中的有效负载的控制台日志没有运行 - 所以我认为肯定有另一个问题 - 我只是找不到任何关于问题可能是什么的信息。

是否有人遇到过长表单无法发布到 Cloud Firestore 的问题?如果我只保留前 10 个问题,则此表单将提交到数据库。

我认为我在 Firestore 的使用限制范围内:

下一次尝试

因此,我从表格中删除了 11-39 的每个问题,并评论了所有 Yup 验证。我一次添加一个问题,发现表单可以正常工作并发布到 Firestore,直到我取消注释验证。他们都通过了——没有错误。所以 - 现在我想知道检查它们的时间是否由 Firestore 计算其进程,也许这会导致超时?那可能吗?如果是这样,有什么方法可以从 Firestore 获得有关这是问题的指示?我的验证如下。

我尝试评论,然后以 10 批取消评论验证。如果我评论从视频到最后的所有验证,表单将成功发布到 firebase。这些验证没有错误。我只是无法将它们成功发布到数据库中。

<Formik
            initialValues={initialValues}
            validationSchema={Yup.object().shape({
                title: Yup.string().required("Give your proposal a title"),
                subtitle: Yup.string().required("Now a subtitle"),
                fieldOfResearch: Yup.array().required("What is your field of research?"),
                disclosureStatus: Yup.string().nullable().required("Some projects are sensitive. Choose a disclosure setting."),
                overview: Yup.string().required("Outline your proposal"),
                objective: Yup.string().required("What is your objective?"),
                currentThinking: Yup.string().required("Outline the current thinking"),
                innovationStatement: Yup.string().required("If this proposal progresses previous research, what are the next steps that are being considered? If it is a paradigm shift, what has prompted it?"),
                influence: Yup.string().required("How is this proposal influenced by prevailing opinion?"),
                layperson: Yup.string().required("How would you describe this research to someone new to your field?"),
                elevator: Yup.string().required("Give it a try."),
                // video:
                resourcesConfirmation: Yup.string().required("Do you have access to research infrastructure you will need?"),
                participantPlan: Yup.string().required("Do you have a plan for how you will recruit participants for this research proposal? If your study does not require participants, then NA will do the job here."),
                resourceRequests: Yup.array().required('What sort of resources are you seeking?'),
                resourceOffers: Yup.array().required('What sort of resources will you bring to this project?'),
                technique: Yup.string().required("Ideally, this answer looks something close to 'Yes, because...' or a 'No, but this team is amazing and will master these techniques in no time, because...'"),
                pitfalls: Yup.string().required("If you've tried to look at this objectively, and can't see any pitfalls, then 'Not Applicable' will do here."),
                community: Yup.string().required("It can be a good idea to do this. If you do, you'll show sensitivity to the interests of others in your field and may open doors for potential collaborations and translation opportunities."),
                samplesize: Yup.string().required("These questions address research quality issues that funders are assessing in considering a proposal."),
                methodDescription: Yup.string().required("What approach will you take in this research?"),
                qualityControls: Yup.string().required("What controls will you put in place? These should address participants, comparators and any interventions."),
                sopAdoption: Yup.string().required("Describe at a summary level, any part of the Statement of Procedures that you have proposed that is noteworthy for reviewers."),
                participantNotification: Yup.string().required("Will you notify participants (if there are any) about the outcomes of this research? If so, describe how that will be done."),
                preregisterPlatform: Yup.string().nullable().required("Select preregistration intention"),
                teamOverview: Yup.string().required("Summarise the collective capabilities and experience of the team making this proposal"),
                proposalLead: Yup.string().required("Enter the name of the team leader"),
                indigenous: Yup.string().required("Either outline the contribution of indigenous team members or mark this field 'Not Applicable'"),
                teamSkillGap: Yup.string().required("Either outline the contribution of indigenous team members or mark this field 'Not Applicable'"),
                performanceIndicators: Yup.string().required("Either outline the performance indicators or mark this field 'Not Applicable'"),
                timeline: Yup.string().required("Either outline the milestones or mark this field 'Not Applicable'"),
                confirmationTeamLead: Yup.boolean().oneOf(
                    [true],
                    "Confirmation that you and each team member has reviewed each of the applicable policies is required"
                ),
                outcomeOverview: Yup.string().required("How might your study contribute to knowledge in the field?"),
                potentialApplications: Yup.string().required("Do you have any insight into potential applications for this research?"),
                potentialResearchAngles: Yup.string().required("Are there any tangential research questions that you think might follow from this study?"),
                budget: Yup.string().required("Attach a link to your project budget?"),
                ethicsIssue: Yup.array().required("Complete your ethics assessment"),
                ethicsManagementPlan: Yup.string().required("Add an ethics management plan, or if there are no issues, complete this field with 'Not Applicable'"),
                conflict: Yup.string().required("Are there any conflicts of interest?"),
                reproducibility: Yup.string().required("How will you approach reproducibility?"),
            })}

【问题讨论】:

  • 你能多贴一点你的代码吗?具体来说,handleSubmit 是如何连接到 Formik 的,它是如何传递给您的表单/按钮的?另外,你在做任何验证吗?控制台登录 handleSubmit 没有触发的事实意味着它可能没有正确连接,或者没有通过验证。
  • 我可以通过删除一些问题让一切正常。表格中有 39 个。如果我只是删除问题 11-39,表格就会提交。我可以尝试一一添加每个问题,但这似乎很奇怪,因为没有发生验证错误
  • 你有任何验证吗?尝试控制台记录errors 或评论validate 属性。该数据似乎不足以调试。一个codesandbox会很有帮助
  • 您应该查看并分享console.error()的消息。并检查您的 Firestore 安全规则和数据大小。见firebase.google.com/docs/firestore/security/get-started,或firebase.google.com/docs/firestore/storage-size
  • 这就是我的观点。控制台中没有错误。没有验证失败。我已经阅读了 Cloud Firestore 文档几次。我不知道我的总限制是多少个字符。我的表格中有 39 个问题。为了测试,我为每个字符串值使用了一个字符,并且有 5 个选择字段,最大选择大小为 20 个字符。我很确定这会保持在 Firestore 的限制范围内 - 但 Firestore 没有关于尝试提交被拒绝的数据的反馈。没有! firebase 是否有任何工具可用于检查这是否是一个问题

标签: reactjs firebase google-cloud-firestore formik yup


【解决方案1】:

我赌你发送到 firestore 的对象在(11-39 问题)中有一些字段,其中包含 undefinednull 值。

在发送到firestore之前尝试清除那些未定义的值,因为Firestore不会保存undefined值并会抛出错误。

// You can send this to firestore.
const payload = {
  a: 1,
  b: 'text value',
  c: [{ id: 432 }]
}

// You canNOT send this to firestore.
const payload = {
  a: 1,
  b: undefined,
  c: [{ id: 432 }]
}

【讨论】:

  • 嗨 - 不,我已成功将所有 39 个问题添加到 Firestore。导致问题的部分是从视频到结束的 Yup 验证。我一一检查了每个qn。他们都工作。没有任何初始值设置为空。他们都是''。
【解决方案2】:
My console log to see the payload in the handleSubmit isn't running...
  • 这很重要。这意味着问题出在 Formik 上。不在 Firebase 中。

  • 评论 fsDB 部分。将handleSubmit 块包装在try/catch 中,console.log 是try 部分,console.error 是catch 部分。此外,在有效负载声明之前添加一个 console.log。您获得的信息应该能解释导致问题的原因。

为了调试,我的意思是把handleSubmit替换为:

handleSubmit = (formState, { resetForm }) => {
    try {
        console.log('TRY');
        // Now, you're getting form state here!
        const payload = {
        ...formState,
        fieldOfResearch: formState.fieldOfResearch.map(t => t.value),
        preregisterPlatform: formState.preregisterPlatform.value,
        resourceRequests: formState.resourceRequests.map(t => t.value),
        resourceOffers: formState.resourceOffers.map(t => t.value),
        ethicsIssue: formState.ethicsIssue.map(t => t.value),
        disclosureStatus: formState.disclosureStatus.value,
        createdAt: firebase.firestore.FieldValue.serverTimestamp()
          }
          console.log("formvalues", payload);

        /*
        fsDB
          .collection("project")
          .add(payload)
          .then(docRef => {
        console.log("docRef>>>", docRef);
        resetForm(initialValues);
          })
          .catch(error => {
        console.error("Error adding document: ", error);
          });
        */

    } catch (reason) {
           console.error('CATCH', reason)
    }
  };

【讨论】:

  • 我该怎么做?
【解决方案3】:

您的验证架构可能是问题所在。您是否尝试过从一开始就删除形状位,我没有看到他们像在 Formik 文档中那样使用它,他们只是使用 Yup.object({validation here})

validationSchema={Yup.object({
                title: Yup.string().required("Give your proposal a title"),
                subtitle: Yup.string().required("Now a subtitle"),
                fieldOfResearch: Yup.array().required("What is your field of research?"),
                disclosureStatus: Yup.string().nullable().required("Some projects are sensitive. Choose a disclosure setting."),
                overview: Yup.string().required("Outline your proposal"),
                objective: Yup.string().required("What is your objective?"),
                currentThinking: Yup.string().required("Outline the current thinking"),
                innovationStatement: Yup.string().required("If this proposal progresses previous research, what are the next steps that are being considered? If it is a paradigm shift, what has prompted it?"),
                influence: Yup.string().required("How is this proposal influenced by prevailing opinion?"),
                layperson: Yup.string().required("How would you describe this research to someone new to your field?"),
                elevator: Yup.string().required("Give it a try."),
                // video:
                resourcesConfirmation: Yup.string().required("Do you have access to research infrastructure you will need?"),
                participantPlan: Yup.string().required("Do you have a plan for how you will recruit participants for this research proposal? If your study does not require participants, then NA will do the job here."),
                resourceRequests: Yup.array().required('What sort of resources are you seeking?'),
                resourceOffers: Yup.array().required('What sort of resources will you bring to this project?'),
                technique: Yup.string().required("Ideally, this answer looks something close to 'Yes, because...' or a 'No, but this team is amazing and will master these techniques in no time, because...'"),
                pitfalls: Yup.string().required("If you've tried to look at this objectively, and can't see any pitfalls, then 'Not Applicable' will do here."),
                community: Yup.string().required("It can be a good idea to do this. If you do, you'll show sensitivity to the interests of others in your field and may open doors for potential collaborations and translation opportunities."),
                samplesize: Yup.string().required("These questions address research quality issues that funders are assessing in considering a proposal."),
                methodDescription: Yup.string().required("What approach will you take in this research?"),
                qualityControls: Yup.string().required("What controls will you put in place? These should address participants, comparators and any interventions."),
                sopAdoption: Yup.string().required("Describe at a summary level, any part of the Statement of Procedures that you have proposed that is noteworthy for reviewers."),
                participantNotification: Yup.string().required("Will you notify participants (if there are any) about the outcomes of this research? If so, describe how that will be done."),
                preregisterPlatform: Yup.string().nullable().required("Select preregistration intention"),
                teamOverview: Yup.string().required("Summarise the collective capabilities and experience of the team making this proposal"),
                proposalLead: Yup.string().required("Enter the name of the team leader"),
                indigenous: Yup.string().required("Either outline the contribution of indigenous team members or mark this field 'Not Applicable'"),
                teamSkillGap: Yup.string().required("Either outline the contribution of indigenous team members or mark this field 'Not Applicable'"),
                performanceIndicators: Yup.string().required("Either outline the performance indicators or mark this field 'Not Applicable'"),
                timeline: Yup.string().required("Either outline the milestones or mark this field 'Not Applicable'"),
                confirmationTeamLead: Yup.boolean().oneOf(
                    [true],
                    "Confirmation that you and each team member has reviewed each of the applicable policies is required"
                ),
                outcomeOverview: Yup.string().required("How might your study contribute to knowledge in the field?"),
                potentialApplications: Yup.string().required("Do you have any insight into potential applications for this research?"),
                potentialResearchAngles: Yup.string().required("Are there any tangential research questions that you think might follow from this study?"),
                budget: Yup.string().required("Attach a link to your project budget?"),
                ethicsIssue: Yup.array().required("Complete your ethics assessment"),
                ethicsManagementPlan: Yup.string().required("Add an ethics management plan, or if there are no issues, complete this field with 'Not Applicable'"),
                conflict: Yup.string().required("Are there any conflicts of interest?"),
                reproducibility: Yup.string().required("How will you approach reproducibility?")
            })}

【讨论】: