12
votes

I have a react app that uses Formik for forms and Cloud Firestore for the database.

I am trying to save the form data in Cloud Firestore. I get no errors in my console or react inspector tools, and when I press submit, I can see in the react inspect tool that the button goes to disabled and then enabled again, but the form doesn't clear the data and the data does not get sent to Cloud Firestore.

My handleSubmit function has:

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);
      });
  };

My submit button has:

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

The form is long - it has 39 questions, I can see from my Cloud Firestore data usage that I'm no where close to the limits for reads and writes. I don't know how to measure the size of my form submit data to know if the form data exceeds Cloud Firestore limits - is there a way to get Firestore to tell you if that's why the submit isn't working?

My console log to see the payload in the handleSubmit isn't running - so I think there must be another issue - I just can't find any information on what the problem might be.

Has anyone had an issue with long forms not posting to Cloud Firestore? If i keep the first 10 questions only, this form submits to the database.

I think I am well within my usage limits on firestore:

enter image description here

NEXT ATTEMPT

So, I took each of questions 11-39 out of the form and commented all of the Yup validations. I added the questions back one at a time and found that the form works and posts to firestore, until I uncommented the validations. They all pass - there are no errors. So - now I'm wondering if the time it costs to check them is counted by firestore for its process and maybe that's causing a time out? Is that possible? If so, is there any way to get an indication from Firestore that this is the problem? My validations are below.

I tried commenting and then uncommenting the validations in batches of 10. The form posts to firebase successfully if I comment all the validations from video down to the end. There are no errors in these validations. I just can't have them as well as successful posting to the database.

<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?"),
            })}
3
Can you post a little more of your code? Specifically, how is handleSubmit hooked up to Formik, and how is it getting passed down to your form/Button? Also, are you doing any validation? The fact that the console log in handleSubmit isn't firing means it's likely either not wired up correctly, or not passing validation.helloitsjoe
I can get everything working by removing some of the questions. There are 39 in the form. If I just delete questions 11-39, the form submits. I can try adding each question one by one, but it seems odd since no validation errors are occurringMel
You got any validation? Try console logging errors or commenting validate attribute. This data seems insufficient to debug. A codesandbox will be great helpDani Vijay
You should check and share the message which console.error(). And check your firestore security rules, and data size. See firebase.google.com/docs/firestore/security/get-started ,or firebase.google.com/docs/firestore/storage-size .zkohi
that's my point. There are no errors in the console. no validation failures. I have read the Cloud Firestore documents a few times. I can't figure out how many characters is my total limit. There are 39 questions in my form. For testing, I used a single character for every string value, and there are 5 select fields, with max select size of 20 characters. I'm pretty sure that keeps within the firestore limit - but there is no feedback from firestore on trying to submit data that is rejected. Nothing! Is there any tool that firebase makes available to check if this is a problemMel

3 Answers

0
votes

I'm betting my money on that the object you send to firestore has some fields in (11-39 question) has undefined or null value in it.

Try clear those undefined value before send to firestore, because Firestore won't save undefined value and will throw error.

// 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 }]
}
0
votes
My console log to see the payload in the handleSubmit isn't running...
  • This is important. This means that the problem is in Formik. Not in Firebase.

  • Comment the fsDB part. Wrap the handleSubmit block in a try/catch and console.log the try part and console.error the catch part. Also, add a console.log before the payload declaration. The information you get should explain what causes the problem.

In order to debug, I mean replace handleSubmit with:

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)
    }
  };
0
votes

Possibly your validation schema is the issue. Have you tried removing the shape bit from the start, I do not see them using it like that in the Formik docs they just use 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?")
            })}