Reputation: 521
When trying to add new item (request) for a collection in my Firestore, Although The item is properly inserted to the collection - I'm getting an error that I can't figure.
updated
Unhandled error RangeError: Maximum call stack size exceeded at isLength (/srv/node_modules/lodash/lodash.js:11739:22) at isArrayLike (/srv/node_modules/lodash/lodash.js:11359:31) at keys (/srv/node_modules/lodash/lodash.js:13333:14) at /srv/node_modules/lodash/lodash.js:4920:21 at baseForOwn (/srv/node_modules/lodash/lodash.js:2990:24) at Function.mapValues (/srv/node_modules/lodash/lodash.js:13426:7) at encode (/srv/node_modules/firebase-functions/lib/providers/https.js:184:18) at /srv/node_modules/lodash/lodash.js:13427:38 at /srv/node_modules/lodash/lodash.js:4925:15 at baseForOwn (/srv/node_modules/lodash/lodash.js:2990:24)
HTML
<!-- new request modal -->
<div class="new-request">
<div class="modal">
<h2>New request</h2>
<form>
<input type="text" name="request" placeholder="request...">
<button>Add</button>
<p class="error"></p>
</form>
</div>
</div>
app.js
// add a new request
const requestForm = document.querySelector(".new-request form");
const requestModal = document.querySelector(".new-request");
requestForm.addEventListener("submit", (e) => {
e.preventDefault();
const addRequest = firebase.functions().httpsCallable("addRequest");
addRequest({
text: requestForm.request.value,
})
.then(() => {
requestForm.reset();
requestModal.classList.remove("open");
requestForm.querySelector(".error").textContent = "";
})
.catch((error) => {
requestForm.querySelector(".error").textContent = error.message;
});
});
index.js (firebase functions) updated*
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();
// auth trigger (user sign up)
exports.newUserSignup = functions.auth.user().onCreate((user) => {
// for background triggers you must return a value/promise
return admin.firestore().collection("users").doc(user.uid).set({
email: user.email,
upvotedOn: [],
});
});
// auth trigger (user deleted)
exports.userDeleted = functions.auth.user().onDelete((user) => {
// for background triggers you must return a value/promise
const doc = admin.firestore().collection("users").doc(user.uid);
return doc.delete();
});
// http callable function (adding a request)
exports.addRequest = functions.https.onCall((data, context) => {
if (!context.auth) {
throw new functions.https.HttpsError(
"unauthenticated",
"only authenticated users can add requests"
);
}
if (data.text.length > 30) {
throw new functions.https.HttpsError(
"invalid-argument",
"request must be no more than 30 characters long"
);
}
return admin.firestore().collection("requests").add({
text: data.text,
upvotes: 0,
});
});
Upvotes: 1
Views: 1131
Reputation: 4641
This issue is similar to this one: https://stackoverflow.com/a/52569728/6016470
You should not directly return the Promise<DocumentReference> produced by your call to firestore as the result of your Cloud Function. This is because a DocumentReference is not intended for being sent back as it is not serializable (your error message comes from lodash failing to serialize due to circular references).
So in order to send serializable result, you should modify your functions as such:
exports.addRequest = functions.https.onCall((data, context) => {
// ...
return admin.firestore().collection("requests").add({
text: data.text,
upvotes: 0,
}).then(doc => {
return doc.id;
});
});
This way, your Cloud Function now returns a Promise<string>, so it can send back its result to your client.
Upvotes: 2