firebase - add and remove new values into an array - javascript

I have two array in firebase realtime database that will manage user followers and following. I've created this function in my vue app that will add the follow if an user click on the button in the profile of another user and the following into the profile of the user who clicked:
async followUser() {
await update(ref(db, 'Users/'+ this.profileKey), {
followers: [store.currentUser.uid]
})
await update(ref(db, 'Users/'+ store.currentUserKey), {
following: [this.$route.params.uid]
})
}
At the moment I've tested on two profile I've created ad-hoc and the function act as expected but I have a doubt about it. If the user will start follow other users, will the new entries will be added correctly into the existing array or all the data will be overwritten? What's the correct way to push or remove valuse into an array stored in firebase realtime database?

There is no atomic way to add an item to or remove an item from an array in the Firebase Realtime Database API. You'll have to read the entire array, add the item, and write the array back.
Better would be to store the followers and followings as maps instead of arrays, with values of true (since you can't have a key without a value in Firebase. If you'd do that, adding a new user follower would be:
set(ref(db, 'Users/'+ this.profileKey+'/followers/'+store.currentUser.uid), true)
And removing a follow would be:
set(ref(db, 'Users/'+ this.profileKey+'/followers/'+store.currentUser.uid), null)
Or
remote(ref(db, 'Users/'+ this.profileKey+'/followers/'+store.currentUser.uid))
Also see: Best Practices: Arrays in Firebase.

Related

Eliminating documents from Firebase Realtime database (Not the entire collection)

I have deployed an app with React and I am using Firebase Realtime database to store some info about attention tickets in a call center. The database will store aprox 80 tickets info per day, but this is cumulative. I want to avoid this so I will not reach the firebase storage limit.
My idea so far is to delete every day at noon the tickets from the database, so It will only store the data from the current date and eliminate it at noon.
I am using remove() function from firebase, but when I tried referencing to the collection, It was entired deleted, I just want to delete the documents but not the entire collection.
Is there a way to specify Firebase to delete docs only, maybe to delete every docs except one?
This is the bunch of code that I pretend to use for deleting (Based on JS)
function deletedata(){
const dbRef = query(ref(db,'/mycollectionpath'));
onValue(dbRef, (snapshot)=>{
snapshot.forEach(childSnapshot=>{
let keyName = childSnapshot.key;
remove(dbRef);
})
});
}
setInterval(deletedata,1000)
The Firebase Realtime Database automatically creates parent nodes when you write a value under them, and it automatically deletes parent nodes when there are no longer any values under them. There is no way to have a node without a value.
If you want to keep the node, consider writing a dummy value. For example, this would remove all child nodes from mycollectionpath and replace them with a single true value:
const dbRef = ref(db, '/mycollectionpath');
dbRef.set(true);

How to get value from firebase without the snapshot key [JS]

Im trying to make friends system but in invite accept i have to delete invite of a guy in his list but i cant do it without the key.
How do i get the snapshot key by value (in this case uid) in database?
Firebase Realtime Database queries work on single path, and then order/filter on a value at a fixed path under each direct child node. In your case, if you know whether the user is active or pending, you can find a specific value with:
const ref = firebase.database().ref("friends");
const query = ref.child("active").orderByValue().equalTo("JrvFaTDGV6TnkZq6uGMNICxwGwo2")
const results = query.get();
results.forEach((snapshot) => {
console.log(`Found value ${snapshot.val()} under key ${snapshot.key}`)
})
There is no way to perform the same query across both active and pending nodes at the same time, so you will either have to perform a separate query for each of those, or change your data model to have a single flat list of users. In that case you'll likely store the status and UID for each user as a child property, and use orderByChild("uid").
Also note that using push IDs as keys seems an antipattern here, as my guess is that each UID should only have one status. A better data model for this is:
friends: {
"JrvFaTDGV6TnkZq6uGMNICxwGwo2": {
status: "active"
}
}

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

Retrieve count data from Firebase like MySQL

When trying to pull data from a MySQL database, I can do something like:
SELECT * FROM users ORDER BY id WHERE vehicle = car
That should get me all the users that drives a car and not show users that drives a motorcycle for instance.
Is there something like this for Firebase? I can only retrieve specific data from one user?
My firebase database is like this: user -> user info (name, age, vehicle etc..)
I want to query every user that drives a car and display them in a row. How do I do that?
I have tried the following, but I didn't succeed with what I tried to do, since after users the users id is the next child. Is there a way to query past that?
var recents = firebase.database().child('users').orderByChild('department').equalTo(department);
recents.on('child_added', function(snapshot) {
var countOfUserInDepartment = snapshot.count;
document.querySelector("#cphCount").innerHTML = countOfUserInDepartment;
});
There are no count queries (nor other aggregation queries) in the Firebase Database. Your options are:
Retrieve all data matching your query and count client-side
Keep a separate count-node that you update whenever you add/remove items.
For #2 you may find it convenient to use Cloud Functions, for which there an an example of keeping such a counter.
Also see:
Firebase count group by
Database-style Queries with Firebase
In Firebase, is there a way to get the number of children of a node without loading all the node data?
How to get size of an element/list in Firebase without get it all?

Firebase order query $UIDs by value at a different node

I'm having trouble trying to figure out how to get a list to query as desired. Full disclosure, it may not be possible and if that's the case then at least it will provide me with some closure. I want to query a friend's list based on presence, where friends who are active are queried on top.
Here is my database structure:
friendships
$UID
$UID: true
users
$UID
active:true/false
I need the list to stay synced so I need to use .on('value'). I've tried a couple different methods using child_added as well as iterating through a snapshot using snapshot.forEach() and pushing the childSnapshot key:value pairs into an array so I could then use lodash to order the list via the active key on the client side, but ran into the issue of it pushing a "new" item into the array for each active value change so there would be multiple items for any given user.
Any help or insight would be appreciated, spent the majority of yesterday attempting to figure this out before resorting back to an unorganized list using the following code:
const {currentUser} = firebase.auth();
firebase.database().ref(`/friendships/${currentUser.uid}`).on('value, snapshot => { //redux dispatch action, payload: snapshot.val() })
There's no great solution for this. Firebase doesn't have any sort of join or join query, so you could do usersRef.orderByChild('active').equalTo(true), but that will just return you all active users. You'll need to do separate queries to pull in their friendships.

Categories

Resources