How to delete parent key by its value in firebase using javascript - javascript

So I'm a newbie in using firebase real time database and I can't delete products key child with id specified.
I've tried this approach but it didn't yield any success:
removeProductById = async (id, user) => {
const userProductRef = db.ref(`products/product`);
try{
var query = userProductRef.orderByChild('id').equalTo(id);
query.remove()
})
}catch(error){
console.log(`The error has occured ${error.message}`)
}
}
So I wanna know how can one delete any tipe of key by whatever value they specify. Thank you in advance, you have always helped me guys.

There are two problems here:
Your query doesn't match the nodes you want delete.
Firebase doesn't support delete-queries.
Your query doesn't match the nodes you want delete
Your query starts at a node products/product, which doesn't exist in your database, and then orders/filters the id property of each child node.
What you want instead is to start at the products node, and then order/filter on its product/id property of each child node:
In code:
const userProductRef = db.ref(`products`);
var query = userProductRef.orderByChild('product/id').equalTo(id);
Don't forget that you'll need to define an index for product/id for this on the products level in your rules.
Firebase doesn't support delete-queries
You can't simply pass the query and delete instruction to Firebase. To write a node in the database, you'll need to know the entire path to that node.
So you'll need to:
Execute the a query.
Loop over the results in your application code.
Delete each matching node individually or in a multi-path update.
With the query above, that'd be:
query.once("value").then((snapshot) => {
snapshot.forEach((child) => {
child.ref.remove();
});
})
Or with a multi-path/batch update:
query.once("value").then((snapshot) => {
let updates = {};
snapshot.forEach((child) => {
updates[child.key] = null;
});
ref.update(updates);
})

Related

Firebase Firestore: How to update or access and update a field value, in a map, in an array, in a document, that is in a collection

Sorry for the long title. Visually and more precise, I would like to update the stock value after a payment is made. However, I get stuck after querying the entire document (e.g. the selected one with title sneakers). Is there a way to actually query and update for example the Timberlands stock value to its value -1. Or do you have to get all data from the entire document. Then modify the desired part in javascript and update the entire document?
Here is a little snippet of a solution I came up with so far. However, this approach hurts my soul as it seems very inefficient.
const updateFirebaseStock = (orders) => {
orders.forEach( async (order) => {
try {
collRef = db.doc(`collections/${order.collectionid}`);
doc = await collRef.get();
data = doc.data();
//Here:const newItems = data.items.map(if it's corr name, update value, else just return object), results in desired new Array of objects.
//Then Update entire document by collRef.update({items: newItems})
} catch (error) {
console.error(error)
};
});
}
You don't need to get the document at all for that, all you have to do is use FieldValue.increment(), using your code as a starting point it could look like this:
collRef = db.doc(`collections/${order.collectionid}`);
collRef.update({
Price: firebase.firestore.FieldValue.increment(-1)
});
You can increment/decrement with any numeric value using that function.

How can i get an element from array by index using firestore

I want to show the users elements from the array one after another when each time the user can exit or continue to the next element. The array is part of a document in firestore. How can i query firestore to retrieve specific element by index?
How can I query Firestore to retrieve specific element by index?
If you want to get a specific element of a field of type Array of a Firestore document, you need to fetch the entire document, get the value from this Array field (which is a JavaScript Array) and then extract the desired data as you would for any JavaScript Array.
There isn't any option, with the Client SDKs, to fetch only a subset of the document fields. It is possible with the REST API, but not with the Client SDKs.
So very concretely, you would as follows:
var docRef = db.collection("cities").doc("SF");
docRef.get().then((doc) => {
if (doc.exists) {
const arrayField = doc.data().arrayField;
// arrayField is a JavaScript Array, you can use any method or property
// e.g. get index 0
const arrayFieldFirstElement = arrayField[0];
} else {
// doc.data() will be undefined in this case
console.log("No such document!");
}
}).catch((error) => {
console.log("Error getting document:", error);
});

Conditinal database record delete firebase

I want to clean some records of a firestore database. I have a function that receives the records I would like to keep, I check in all the records if id is not in the docsToKeep:firebase documents argument.
I use a foreach for all the records, and I user filter to find the matching id as shown in the working snippet below:
async function checkForNotifClean(docsToKeep:firebase.firestore.QuerySnapshot<firebase.firestore.DocumentData>) {
const db = firebase.firestore();
const notifCollection = db.collection('notifications')
const allData = await notifCollection.get();
allData.docs.forEach(doc => {
const filtered = docsToKeep.docs.filter(entry => entry.id === doc.id);
const needsErase = filtered.length === 0;
if (needsErase) {
const id = doc.id;
notifCollection.doc(id).delete();
}
})
}
Is there a cleaner way to erase all the documents that are not in docsToKeep ? Would be kind of function that get all the objects that are not in both arrays and delete those. I would be happy on improvements on the javascript side to filter out the records to delete, and in the firebase side, improvements regarding the chance of deleting some set of records at once instead of looping through all and deleting each.
To delete (or write to) a document in Firestore you need to know the complete path to that document, including its document ID. If you don't have the IDs of the documents to delete, then your only option is to determine those IDs as you're doing now.
It does lead to the question how docsToKeep is populated though. My guess it that the user already selects some documents from a full list. If that's the case, might you be able to pass the inverted list: docsToDelete?

Saving a field from firestore that is an array

I am currently working on a mobile app on React and I am having trouble understanding how to save a field from fire store that is an array.
Since I can't post images my database structure is all strings such as username, first name, etc but I have a field called follow list that is an array.
What I want to do is save the usernames from the following list into an array to later search fire store for the username's in the array, this is basically what I want to do so I can render my app's social Feed. I do know that I can probably create another subcollection and write something familiar to what I did to search for users but that was a QuerySnapShot which was overall documents not a specific one and I also know firebase creates an ID for arrays and it increases as the array gets bigger.
I do not want to end up making two more subcollections one for followers and following which I think not ideal right? My current approach is this
export const fetchUserFollowing = async (username) => {
const ref = firebase.firestore().collection('users').doc(username)
let results = []
ref
.get()
.then( doc => {
let data = doc.data()
results = data
})
.catch((err) => {
return 'an error has occurred ', err
})
}
From what I understand is that a DocumentSnapShot .get() function returns an object but what I want is to store follow list into results and then return that but I am not sure how to manipulate the object return to just give me follow List which is an array
https://rnfirebase.io/docs/v5.x.x/firestore/reference/DocumentSnapshot
link to docs

Get the child object of a limit(1) query on firebase database

I have this data
I do this query
firebase.database().ref(${path}/buy)
.orderByChild('price').limitToFirst(1)
.once('value')
.then(snapshot => console.log(snapshot.val()))
And I get this result
Then the question is
Is there an easy way to access the price attribute of the one object whose key I don't know?
e.g. snapshot.first().price or snapshot.only().price
Simply put, I want to avoid this
var result = snapshot.val()
var key = Object.keys(result)[0]
var price = result[key].price
When you execute a query against the Firebase Database, there will potentially be multiple results. So the snapshot contains a list of those results. Even if there is only a single result, the snapshot will contain a list of one result.
In your callback you need to handle this list by using snapshot.forEach():
firebase.database().ref(${path}/buy)
.orderByChild('price').limitToFirst(1)
.once('value')
.then(snapshot => {
snapshot.forEach(function(child) {
console.log(child.val());
console.log(child.val().price);
})
})

Categories

Resources