A call like this can fail silently:
await update(ref, {...properties})
Even though this is a promise, using then/catch doesn't catch the error. If you wrap the entire thing in try/catch, you can see the error:
try{
await update(ref, {...properties})
} catch (error) {
console.log(error)
}
console:
Error: update failed: values argument contains undefined in property...
Since this was maddening, I wanted to share the answer.