Firebase query and delete data in javascript - javascript

Here is my firebase
I would like to delete the last deed within deeds which happens to be deed id: 1. I would like to do this without specifying anything other than deleting the last deed in deeds.
Here is what I have tried already, but I receive no function errors because i'm returning query type objects.
const deedRef = admin.database().ref('/deeds');
deedRef.limitToLast(1).once("value", (snapshot) => {
snapshot.val().remove();
})
And
const deedRef = admin.database().ref('/deeds');
deedRef.limitToLast(1).once("value", (snapshot) => {
snapshot.forEach((deedSnapshot) =>{
deedSnapshot.remove();
})
})
And I've tried this
const deedRef = admin.database().ref('/deeds');
deedRef.limitToLast(1).remove();
How can I reference the last deed in deeds and remove it? The last deed will constantly change.

You were getting close:
const deedRef = admin.database().ref('/deeds');
deedRef.limitToLast(1).once("value", (snapshot) => {
snapshot.forEach((deedSnapshot) =>{
deedSnapshot.ref.remove();
})
})

Related

array.prototype..forEach function skipped with values in variable

I have a problem, i have a Firebase Firestore Database connected to my React.JS Project, where users can enroll to courses. Now if i'm trying to load the users collection from the DB it returns 1 entry.
const fetchAthletes = async () => {
debugger
try {
const athletes: Array<any> = [];
const athleteRef = collection(db, COLLECTION_NAME_ATHLETE);
const getAthleteQuery = query(athleteRef, where('user', '==', userAuthToken.accessToken));
const querySnapshot = await getDocs(getAthleteQuery)
if (querySnapshot.docs) {
//this for each gets skipped, even when querySnapshot.doc has values in it
querySnapshot.forEach((doc) => {
athletes.push({
id: doc.id,
...doc.data()
});
setAthletes(athletes as Array<Athlete>);
})
}
} catch (error: unknown) {
enqueueSnackbar((error as string), { variant: 'error', autoHideDuration: 3000 })
}
}
But when i want to loop over it via array.prototype.map it always skips it.
I debbuged through the funtion and found out that docs from Firestore is set with values tbat i wanna recieve.
Data returned by Firestore
I have no clue why it doesn't work. Any idea or help is appreciated
Rather than attempt to individually set each doc into state, build up your array and set the entire thing into state
const querySnapshot = await getDocs(getAthleteQuery);
setAthletes(querySnapshot.docs.map((doc) => ({
id: doc.id,
...doc.data(),
}));

Why does my DBSearch function keep looping when pulling data from Firebase?

New to coding last month and I'm learning JS through React Native.
I've added a Firestore DB to pull data through to my app and put together a call-back function using the useState hook due to it being Async.
My issue is my DBSearch function is now looping infinitely.
Code below:
const [propertyData, setPropertyData] = React.useState(["Well, this is awkward..."])
const colRef = (listName) => collection(db, listName)
const dbSearch = (listName, callBackFuncHere) => {onSnapshot(colRef(listName), (snapshot) => {
let newList = []
snapshot.docs.forEach(doc => {
newList.push({ ...doc.data(), id: doc.id }) // Pulls Object Data and runs for loop to assign to newList Array
})
callBackFuncHere(newList)
})};
function retFunc(newList){
setPropertyData(newList)
console.log('1')
}
dbSearch('propertyList', retFunc)
Is this an improper use for useState? and how should I change my dbSearch function to stop it continually looping?
Apologies if this has been asked a thousand times before, I'm unsure how to clearly articulate and search for my problem.

react-native-firebase query with 'array-contains' in useEffect keeps refreshing component

I'm just trying to make a request to fetch only the threads that contain the current user's id.
If I remove my 'where' query, I can fetch all threads.
There is my code :
useEffect(() => {
const unsubscribe = firestore()
.collection('THREADS')
// query is empty
.where('usersIds', 'array-contains', ['60ddd70c7a3a1e8e62d14dac'])
.orderBy('latestMessage.createdAt', 'desc')
.onSnapshot(querySnapshot => {
const threadsQueried = querySnapshot
? querySnapshot.docs.map(documentSnapshot => {
return {
...documentSnapshot.data(),
};
})
: null;
setThreads(threadsQueried);
if (loading) {
setLoading(false);
}
});
return () => unsubscribe();
});
I already tried without putting my id into an array, but the component keeps refreshing, like that:
.where('usersIds', 'array-contains', '60ddd70c7a3a1e8e62d14dac')
My firebase datas:
I already check here https://stackoverflow.com/a/59053018/9300663
and here https://stackoverflow.com/a/59215461/9300663
Edit: So it is working when id is without brackets ('60ddd70c7a3a1e8e62d14dac') into the query
But my component keeps refreshing.
If I add an empty array or an array with dependencies to my useEffect, the query does not works anymore.
Edit 2: Query is working but get called two times and the second time get back with 'null', which is emptying my state.
So I found the solution when I tried another way to get my firebase query by using get() instead of onSnapshot():
firestore()
.collection('THREADS')
.where('usersIds', 'array-contains', user.id)
.orderBy('latestMessage.createdAt', 'desc')
.get()
.then(querySnapshot => {
const threadsQueried = querySnapshot.docs.map(documentSnapshot => {
return {
...documentSnapshot.data(),
};
});
setThreads(threadsQueried);
The problem with 'get()' was that the query only worked once and didn't update if new threads were created.
But it allowed me to have a firebase error asking me to create the indexes: 'usersIds' and 'latestMessage.createdAt'. After creating them, I was able to reuse my old code and everything's working correctly now.
useEffect(() => {
const unsubscribe = firestore()
.collection('THREADS')
.where('usersIds', 'array-contains', user.id)
.orderBy('latestMessage.createdAt', 'desc')
.onSnapshot(querySnapshot => {
const threadsQueried = querySnapshot.docs.map(documentSnapshot => {
return {
...documentSnapshot.data(),
};
});
setThreads(threadsQueried);
});
return () => unsubscribe();
}, []);

[TypeError]: Firebase orderByChild not working

I'm trying to query my database such that it retrieves an ordered list based on each child key. I do it as follows (see below), but "TypeError" happens. That is ordered at random when using .on('value', snapshot =>. I can't fix that, do you guys have any ideas to realize?
The Error
TypeError: In this environment the sources for assign MUST be an object. This error is a performance optimization and not spec compliant.
Realtime Database Query
Source Code
export const messagesFetch = (room) => {
return (dispatch) => {
firebase.database().ref(`/rooms/${room.roomId}/messages`)
.once('child_added', snapshot => {
dispatch({ type: 'messages_fetch_success', payload: snapshot.val() });
})
};
};
child_added will create a new snapshot for each message, instead of returning a list of messages in one object.
You might want to look at .once('value') instead of once('child_added').
As you wanted an ordered list I added the query orderByKey() which will return the messages in key order.
export const messagesFetch = (room) => {
return (dispatch) => {
firebase.database().ref(`/rooms/${room.roomId}/messages`)
.orderByKey()
.once('value')
.then(snapshots => {
snapshots.forEach(snapshot => {
dispatch({ type: 'messages_fetch_success', payload: snapshot.val() });
return false;
});
});
};
};
Is a react-native app, right?! If yes add a flag in question.
In firebase 'child_added' fires for each child and ever a new child has add, like sketchthat says. With 'once' you not listen the node, but, because 'child_added' you fires your function for every child. In other words your function return differents values (snapshot) for a same constant.

Error with Firestore update in a Cloud Function

I try to put a listener on Firebase that will replicate a value in the matching element in Firestore.
exports.synchronizeDelegates = functions.database.ref(`delegates/{userId}/activities`).onUpdate((event) => {
const userKey = event.data.ref.parent.key
console.log("User Key:" + userKey)
return admin.database().ref(`delegates/${userKey}/email`).once('value', snapshot => {
let email = snapshot.val()
console.log("Exported Email:" + email)
const userRef = admin.firestore().collection('users')
const firestoreRef = userRef.where('email', "==", email)
firestoreRef.onSnapshot().update({ activities: event.data.toJSON() })
}).then(email => {
console.log("Firebase Data successfully updated")
}).catch(err => console.log(err))
}
)
This function is able to retrieve and locate the elemnt needed to target the right document in firestore, but the .update()function still error firestoreRef.update is not a function
I try several ways to query but I still have this error.
How to properly query then update a document in this scenario?
The onSnapshot() method of Query introduces a persistent listener that gets triggered every time there's a new QuerySnapshot available. It keeps doing this until the listener is unsubscribed. This behavior is definitely not what you want. Also, there's no update() method on QuerySnapshot that your code is trying to call.
Instead, it looks like you want to use get() to fetch a list of documents that match your query, then update them all:
exports.synchronizeDelegates = functions.database.ref(`delegates/{userId}/activities`).onUpdate((event) => {
const userId = event.params.userId
console.log("User Key:" + userKey)
return admin.database().ref(`delegates/${userId}/email`).once('value', snapshot => {
let email = snapshot.val()
console.log("Exported Email:" + email)
const usersRef = admin.firestore().collection('users')
const query = usersRef.where('email', "==", email)
const promises = []
query.get().then(snapshots => {
snapshots.forEach(snapshot => {
promises.push(snapshot.ref.update(event.data.val()))
})
return Promise.all(promises)
})
}).then(email => {
console.log("Firebase Data successfully updated")
}).catch(err => console.log(err))
}
Note that I rewrote some other things in your function that were not optimal.
In general, it's a good idea to stay familiar with the Cloud Firestore API docs to know what you can do.

Categories