I get the user id's which is not contains a specific word. I need to update user status.
var primeusers = [];
var komence= firebase.database().ref();
function thisclick() {
komence.child('Buyers').on("value", function(snapshot) {
snapshot.forEach(function(data) {
if(!data.val().Nealdi.includes("GPA")) {
primeusers.push(data.key);
}
});
console.log(primeusers);
});
}
I can get the user id's.But I can't update their status.
//Update statatus to user under on "Users".
var vipata = firebase.database().ref();
vipata.child("Users").child(`primeusers`).once('value', function (snapshot) {
snapshot.forEach(function(child) {
child.ref.update({Minivip: "NO"});
child.ref.update({VIP: "NO"});
});
});
Database structure.
|-Buyers
|--Userid
|---Nealdi
|-Users
|--Userid
|---Minivip
|---VIP
I'll suppose you forgot the child "primeusers" in the structure schema shown. Try that:
var vipata = firebase.database().ref("Users");
vipata.child(`primeusers`).once('value', function (snapshot) {
snapshot.val().forEach(function(child) {
child.ref.update({Minivip: "NO"});
child.ref.update({VIP: "NO"});
});
});
Note here you are doing an update for each child. You can upgrade that by updating your object in your client side, and then update the entire object in once (it will be more beneficial for you). (I can link you an example if you want one).
Related
Hello I would like to automatically generate an alert in realtime as soon as a value in my Firebase database has changed. My code looks like this:
try {
var ref = firebase.database().ref("URL").child("1");
ref.on("child_changed", function(snapshot) {
var changedPost = snapshot.val();
alert(changedPost);
});
}
catch(err) {
alert("Error");
}
As you can see the structure of my database is:
Could someone tell me what is wrong with this code and why I don't get an alert when something changes in my database?
I would appreciate an answer.
You're listening for child_changed events, which fires when a property under /URL/1 changes. To instead get called when the value in /URL/1 changes, listen for a value event:
ref.on("value", function(snapshot) {
var changedPost = snapshot.val();
alert(changedPost);
});
I want to use firebase's onSnapshot function sequentially. A situation where I want to apply this is given below.
Scenario:
There are 2 collections in firestore. Employees and Projects. In the Employees collection, the docs are storing the details of employees. And it also stores the IDs of Projects docs on which that particular employee is working. In Projects collection, the detail of projects is stored.
Goal:
First, I have to fetch the data from Employees collection related to a specific employee. Then, from the fetched employee data, I will have the project IDs on which he/she is working on. So, from that ID I need to fetch the project details. So, when any information related to project or employee changes, the data on screen should also change in real-time.
Issue:
I tried to write a nested code. But it works realtime only for employee data. It doesn't change when the project detail is updated. Something like this...
admin.auth().onAuthStateChanged(async () => {
if (check_field(admin.auth().currentUser)) {
await db.collection('Employees').doc(admin.auth().currentUser.uid).onSnapshot(snap => {
...
let project_details = new Promise(resolve => {
let projects = [];
for (let i in snap.data().projects_list) {
db.collection('Projects').doc(snap.data().projects_list[i]).onSnapshot(prj_snap => {
let obj = prj_snap.data();
obj['doc_id'] = prj_snap.id;
projects.push(obj);
});
}
resolve(projects);
});
Promise.all([project_details]).then(items => {
...
// UI updation
});
...
});
}
});
What is the correct way for doing this?
You're actually proposing a pretty complex dataflow scenario. I would approach this as a multi-step problem. Your goal is essentially:
If there is a user, listen in realtime for the list of project ids for that user.
For each project id, listen in realtime for details about that project.
(presumably) Clean up listeners that are no longer relevant.
So I would tackle it something like this:
let uid;
let employeeUnsub;
let projectIds = [];
let projectUnsubs = {};
let projectData = {};
const employeesRef = firebase.firestore().collection('Employees');
const projectsRef = firebase.firestore().collection('Projects');
firebase.auth().onAuthStateChanged(user => {
// if there is already a listener but the user signs out or changes, unsubscribe
if (employeeUnsub && (!user || user.uid !== uid)) {
employeeUnsub();
}
if (user) {
uid = user.uid;
// subscribe to the employee data and trigger a listener update on changes
employeeUnsub = employeesRef.doc(uid).onSnapshot(snap => {
projectIds = snap.get('projects_list');
updateProjectListeners();
});
}
});
function updateProjectListeners() {
// get a list of existing projects being listened already
let existingListeners = Object.keys(projectUnsubs);
for (const pid of existingListeners) {
// unsubscribe and remove the listener/data if no longer in the list
if (!projectIds.includes(pid)) {
projectUnsubs[pid]();
delete projectUnsubs[pid];
delete projectData[pid];
render();
}
}
for (const pid of projectIds) {
// if we're already listening, nothing to do so skip ahead
if (projectUnsubs[pid]) { continue; }
// subscribe to project data and trigger a render on change
projectUnsubs[pid] = projectsRef.doc(pid).onSnapshot(snap => {
projectData[pid] = snap.data);
render();
});
}
}
function render() {
const out = "<ul>\n";
for (const pid of projectIds) {
if (!projectData[pid]) {
out += `<li class="loading">Loading...</li>\n`;
} else {
const project = projectData[pid];
out += `<li>${project.name}</li>`;
}
}
out += "</ul>\n";
}
The above code does what you're talking about (and in this case the render() function just returns a string but you could do whatever you want to actually manipulate DOM / display data there).
It's a lengthy example, but you're talking about a pretty sophisticated concept of essentially joining realtime data dynamically as it changes. Hope this gives you some guidance on a way forward!
I want to do a user search vie search bar.when I enter the last name I should receive data about users if there are matches but i don't know how.
here is my try
searchBar(){
let a=app.database().ref('users/'+app.auth().currentUser.uid).orderByChild('/surname').equalTo('Крюкин');
console.log(a);
}
here is structure of data
Try the following:
searchBar(){
let a=app.database().ref('users');
a.orderByChild('surname').equalTo('Крюкин').on('value',((snapshot) => {
snapshot.forEach((childSnapshot) => {
console.log(childSnapshot.val());
});
}
First you are not using a userID, that's a random id generated using push() in your database. Therefore you need to use forEach() to access the data.
Check the guide:
https://firebase.google.com/docs/database/web/read-and-write
you dont exactly read data from firebase.
You should create a handle, which you did, a in your case
and then on that handle you register value event listener the code below is from official docs
ref.once('value', function(snapshot) {
snapshot.forEach(function(childSnapshot) {
var childKey = childSnapshot.key;
var childData = childSnapshot.val();
// ...
});
});
in your case you shloud just to
a.on("value",list=>{list.forEach(...)})
also you can subscribe for future child_added/removed/updated events
here are the docs
I have a firebase realtime database (not cloud) structure like:
users
kasdf872ajsda //user id
auiiq6d182g1 //list id
c: <mycontent> //list content
i know the list id (in this case auiiq6d182g1) and i want to retrieve <mycontent>, but i don't know the user id kasdf872ajsda , because what i'm going to retrieve is probably not from the user currently using the website (and i'm not setting any database rules for "read" in fact, only for "write" is that correct?).
What i'm doing right now is this (not working):
var ref = firebase.database().ref().child('users');
ref.child(listID).once("value", function(snapshot) {
var snap = snapshot.val();
myContent = snap.c;
});
You could put your reference to users first: var ref = firebase.database().ref('users');
Then loop through:
ref.once('value').then((snapshot)=>{
snapshot.forEach(function(data) {
if (data.key == <YOUR_LIST_ID>) {
//you can access data.c here...
}
});
});
Found the solution, if someone should encounter the same issue:
ref.once("value", function(snapshot) {
snapshot.forEach(function(data) {
snap = data.child(<YOUR_LIST_ID>).child('c').val();
if (snap != null){
myContent = snap;
}
});
});
also ref contrary to what everyone says has to be:
var ref = firebase.database().ref().child('users');
this doesn't work:
var ref = firebase.database().ref('users');
I have the following db structure in firebase
I'm trying to grab data that belongs to a specific user id (uid). The documentation has the following example:
firebase.database().ref('/users/' + userId).once('value').then(function(snapshot) {
var username = snapshot.val().username;
// ...
});
But how can I retrieve data from my example without knowing the unique key for each object?
Update:
I tried a new approach by adding the user id as the main key and each child object has it's own unique id.
Now the challenge is how to get the value of "title".
firebase.database().ref('/tasks/').orderByChild('uid').equalTo(userUID)
Well that is pretty straightforward. Then you can use it like this:
return firebase.database().ref('/tasks/').orderByChild('uid').equalTo(userUID).once('value').then(function(snapshot) {
var username = snapshot.val().username;
// ...
});
Of course you need to set userUID.
It is query with some filtering. More on Retrieve Data - Firebase doc
Edit: Solution for new challenge is:
var ref = firebase.database().ref('/tasks/' + userUID);
//I am doing a child based listener, but you can use .once('value')...
ref.on('child_added', function(data) {
//data.key will be like -KPmraap79lz41FpWqLI
addNewTaskView(data.key, data.val().title);
});
ref.on('child_changed', function(data) {
updateTaskView(data.key, data.val().title);
});
ref.on('child_removed', function(data) {
removeTaskView(data.key, data.val().title);
});
Note that this is just an example.