Reputation: 109
I'm still very new to coding so bear with me! I have followed a youtube course to build a note app and get a base to work from, but I'm now getting this error at random times when deleting the notes in firebase, hoping someone might be able to spot what's cooking here!
"Unhandled Rejection (FirebaseError): No document to update: projects/speakle-dc94b/databases/(default)/documents/notes/GdWPrQNxR3Z9TFMWmqOZ"
And it's referencing the node modules like so: screenshot of the error in chrome
The code I have that interacts with firebase looks like this:
componentDidMount = () => {
firebase
.firestore()
.collection('notes')
.onSnapshot(serverUpdate => {
const notes = serverUpdate.docs.map(_doc => {
const data = _doc.data();
data['id'] = _doc.id;
return data;
});
console.log(notes);
this.setState({ notes: notes });
});
}
selectNote = (note, index) => this.setState({ selectedNoteIndex: index, selectedNote: note });
noteUpdate = (id, noteObj) => {
firebase
.firestore()
.collection('notes')
.doc(id)
.update({
title: noteObj.title,
body: noteObj.body,
timestamp: firebase.firestore.FieldValue.serverTimestamp()
});
}
newNote = async (title) => {
const note = {
title: title,
body: ''
};
const newFromDB = await firebase
.firestore()
.collection('notes')
.add({
title: note.title,
body: note.body,
timestamp: firebase.firestore.FieldValue.serverTimestamp()
});
const newID = newFromDB.id;
await this.setState({ notes: [...this.state.notes, note] });
const newNoteIndex = this.state.notes.indexOf(this.state.notes.filter(_note => _note.id === newID)[0]);
this.setState({ selectedNote: this.state.notes[newNoteIndex], selectedNoteIndex: newNoteIndex });
}
deleteNote = async (note) => {
const noteIndex = this.state.notes.indexOf(note);
await this.setState({ notes: this.state.notes.filter(_note => _note !== note) })
if(this.state.selectedNoteIndex === noteIndex) {
this.setState({ selectedNoteIndex: null, selectedNote: null});
} else {
this.state.notes.lenght > 1 ?
this.selectNote(this.state.notes[this.state.selectedNoteIndex - 1], this.state.selectedNoteIndex - 1) :
this.setState({ selectedNoteIndex: null, selectedNote: null });
}
firebase
.firestore()
.collection('notes')
.doc(note.id)
.delete()
.then(function() {
console.log("Document successfully deleted!");
}).catch(function(error) {
console.error("Error removing document: ", error);
});
}
}
Upvotes: 9
Views: 16239
Reputation: 11
Unhandled Rejection (FirebaseError): No document to update:
You can handle the rejection:
updateDoc(routeDocumentRef, {
// Updated Object
}).catch((e) => {
if (e.code === 'not-found') {
// Create a new note
}
// Throw an actual error.
});
}
You can try to update the note if it fails to No document found
, you can check for that error code that gets thrown. If gets thrown you can create it.
Upvotes: 0
Reputation: 581
You could simply do it like this
You
Get it
If it exsits: you update it
If it doesn't exist, you set it.
const docRef = this.db.collection("users_holdings").doc(userId);
docRef.get().subscribe((doc) => {
if (doc.exists) {
docRef.update({
stockHoldings: stockHoldings,
});
} else {
docRef.set({
stockHoldings: stockHoldings,
});
}
});
Upvotes: 2
Reputation: 73
I was working with something like this only especially in Cloud Functions and while writing an endpoint for doing some operation I came across the below-quoted error.
I was trying to read a document in a collection and if it existed I was trying to write a new doc into another collection. So it was kind of a nested code.
A piece of my code.
const firstDocRef = db.collection('myFirstCollection').doc('myDocName');
const existDoc = firstDocRef.get()
.then((resDoc)=>{
if(resDoc.exists)
{
db.collection('mySecondCollection').add({
.
.
.
.
.
orderCreatedAt:Firestore.FieldValue.serverTimestamp()
})
.then((new_doc)=>{
return res.status(200);
// return 200 ok what we were trying to achieve has completed.
})
.catch(()=>{
console.log("Log, as write failed somehow");
return res.status(500);
// return a 500 internal server error occurred
});
}
else
{
console.log("My first condition wasn't met, so logged it");
return res.end();
// properly terminate the processing of request
}
});
/*.catch((err)=>{
console.log("Our first doc presence check couldn't complete and hence I arrived here, log it");
res.writeHead(500);
return res.end();
// again give back 500 to client
});*/
UnhandledPromiseRejectionWarning: ReferenceError: Firestore is not defined UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block
Now I am also new to Firebase but I came across this and somehow solved it.
So I was not getting the above error if I was putting in a catch block in get()
document.
Strange huh!
Removed the catch block by commenting it. Got this error.
Now, this is a haywire error, it says the catch is not there, but we did it on purpose.
So I began searching, came across this question here on stack overflow and saw it's still unanswered. Searched and read the documentation myself.
I would like to tell you that this isn't because of any Firestore Security Rules, or anything else. Because I came across some guesses around these notions too while searching for an answer.
The common thing we all are doing here is that we are trying to achieve the ServerTimeStamp at FireStore
I would like to bring your notice to my imports in my node cloud function code.
const functions = require('firebase-functions');
const express = require('express');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
const db = admin.firestore();
So you see, I am using the new way of getting the permission to use Firestore because I am trying to establish a cloud function.
Now this is the documentation reference provided by Google: Click here!
The right syntax proposed by above API reference is
Firestore.FieldValue.serverTimestamp()
It is the culprit, it isn't providing me any timestamp and if there is not a catch block unhandled promise error is occuring and no error is being shown while debugging, it just doesn't work.
I did this, Solution part:
Even after those imports in my Node Program, I imported this:
const {Firestore} = require('@google-cloud/firestore');
Now all I did was that I used the statement in the timestamp field as
Firestore.FieldValue.serverTimestamp()
Exactly as mentioned and even used a catch block just in case any other problem occurs while at production. That is using db constant to do all the Database Transactional Stuff and just for serverTimeStamp
I have to bring in new import.
And it worked, I guess require('@google-cloud/firestore')
statement imported as {FireStore} brings in all the things that are required for the FieldValue thing to use as a reference.
I hope it helps any new person looking for it and saves a lot of time which I wasted searching for a solution.
I have verified it by running the cloud function on firebase emulator.
Upvotes: 2
Reputation: 156
It simply means that there is no document of that name to be uploaded.
you could either use set()
or add()
to add the document because it is not present.
noteUpdate = (id, noteObj) => {
firebase
.firestore()
.collection('notes')
.doc(id)
.update({
title: noteObj.title,
body: noteObj.body,
timestamp: firebase.firestore.FieldValue.serverTimestamp()
});
}
replace the above code with this
noteUpdate = (id, noteObj) => {
firebase
.firestore()
.collection('notes')
.doc(id)
.add({
title: noteObj.title,
body: noteObj.body,
timestamp: firebase.firestore.FieldValue.serverTimestamp()
});
}
or
noteUpdate = (id, noteObj) => {
firebase
.firestore()
.collection('notes')
.doc(id)
.set({
title: noteObj.title,
body: noteObj.body,
timestamp: firebase.firestore.FieldValue.serverTimestamp()
});
}
Upvotes: 4