fix nested ref values causing side drawer crash (#565)

This commit is contained in:
Sidney Alcantara
2021-10-28 22:37:56 +11:00
parent b1c546cf6b
commit 265dd60f49
2 changed files with 30 additions and 10 deletions

View File

@@ -2,8 +2,6 @@ import { createElement, useEffect } from "react";
import { useForm } from "react-hook-form";
import _sortBy from "lodash/sortBy";
import _isEmpty from "lodash/isEmpty";
import _mapValues from "lodash/mapValues";
import firebase from "firebase/app";
import { Stack } from "@mui/material";
@@ -16,6 +14,7 @@ import FieldWrapper from "./FieldWrapper";
import { useAppContext } from "contexts/AppContext";
import { useProjectContext } from "contexts/ProjectContext";
import { sanitizeFirestoreRefs } from "utils/fns";
export interface IFormProps {
values: Values;
@@ -38,13 +37,7 @@ export default function Form({ values }: IFormProps) {
{}
);
const { ref: docRef, ...rowValues } = values;
const safeRowValues = _mapValues(rowValues, (v) => {
// If react-hook-form receives a Firestore document reference, it tries to
// clone firebase.firestore and exceeds maximum call stack size.
if (firebase.firestore.DocumentReference.prototype.isPrototypeOf(v))
return v.path;
return v;
});
const safeRowValues = sanitizeFirestoreRefs(rowValues);
const defaultValues = { ...initialValues, ...safeRowValues };
const methods = useForm({ mode: "onBlur", defaultValues });

View File

@@ -1,4 +1,8 @@
import firebase from "firebase/app";
import _get from "lodash/get";
import _mapValues from "lodash/mapValues";
import _isPlainObject from "lodash/isPlainObject";
import { TABLE_GROUP_SCHEMAS, TABLE_SCHEMAS } from "config/dbPaths";
/**
@@ -178,7 +182,7 @@ export const deepMerge = (target, source) => {
};
export const rowyUser = (
currentUser: firebase.default.User,
currentUser: firebase.User,
data?: Record<string, any>
) => {
const { displayName, email, uid, emailVerified, isAnonymous, photoURL } =
@@ -195,3 +199,26 @@ export const rowyUser = (
...data,
};
};
const _firestoreRefSanitizer = (v: any) => {
// If react-hook-form receives a Firestore document reference, it tries to
// clone firebase.firestore and exceeds maximum call stack size.
if (firebase.firestore.DocumentReference.prototype.isPrototypeOf(v))
return v.path;
// Also test for arrays
if (Array.isArray(v))
return v.map((w) => {
if (firebase.firestore.DocumentReference.prototype.isPrototypeOf(w))
return w.path;
return w;
});
// Also test for objects
if (_isPlainObject(v)) return _mapValues(v, _firestoreRefSanitizer);
return v;
};
export const sanitizeFirestoreRefs = (doc: Record<string, any>) =>
_mapValues(doc, _firestoreRefSanitizer);