I'm able to query my users array with an e-mail address and return the user's account info:
users.orderByChild('email').equalTo(authData.user.email).once('value').then(function(snapshot) {
console.log(snapshot.val());
console.log(snapshot.key); // 'users'
console.log(snapshot.child('email').key); 'email'
...
How do I get the key (-KiBBDaj4fBDRmSS3j0r). snapshot.key returns users. snapshot.child('email').key returns email. The key doesn't appear to be a child, i.e., it appears to be in between users and email.
You could do something like this:
var key = Object.keys(snapshot.val())[0];
Ref: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
The Object.keys() method returns an array of a given object's own
enumerable properties, in the same order as that provided by a
for...in loop (the difference being that a for-in loop enumerates
properties in the prototype chain as well).
Realtime database:
For this you can simple use: snapshot.key
snapshot = firebase.database.DataSnapshot
this.app.database()
.ref('/data/')
.on('value', function(snapshot) {
const id = snapshot.key;
//----------OR----------//
const data = snapshot.val() || null;
if (data) {
const id = Object.keys(data)[0];
}
});
Firestore:
snapshot.id
snapshot = firebase.firestore.DocumentSnapshot
this.app.firestore()
.collection('collection')
.doc('document')
.onSnapshot(function(snapshot) {
const id = snapshot.id;
//----------OR----------//
const data = snapshot.data() || null;
if (data) {
const id = Object.keys(data)[0];
}
});
users.orderByChild('email').equalTo(authData.user.email) is a Query (doc) that you have built by "chaining together one or more of the filter methods". What is a bit specific with your query is that it returns a dataSnapshot with only one child, since you query with equalTo(authData.user.email).
As explained here, in this exact case, you should loop over the returned dataSnapshot with forEach():
Attaching a value observer to a list of data will return the entire list of data as a single snapshot which you can then loop over to access individual children.
Even when there is only a single match for the query, the snapshot is
still a list; it just contains a single item. To access the item,
you need to loop over the result, as follows:
ref.once('value', function(snapshot) {
snapshot.forEach(function(childSnapshot) {
var childKey = childSnapshot.key;
var childData = childSnapshot.val();
// ...
});
});
Similar to camden_kid, I used Object.keys(arr), but in three lines:
var arr = snapshot.val();
var arr2 = Object.keys(arr);
var key = arr2[0];
console.log(key) // -KiBBDaj4fBDRmSS3j0r
I found new way to get the data based on snapshot key -
firebase.database().ref('events').once('value',(data)=>{
//console.log(data.toJSON());
data.forEach(function(snapshot){
var newPost = snapshot.val();
console.log("description: " + newPost.description);
console.log("interest: " + newPost.interest);
console.log("players: " + newPost.players);
console.log("uid: " + newPost.uid);
console.log("when: " + newPost.when);
console.log("where: " + newPost.where);
})
})
Related
I'm using MERN stack for my program with mongoose for accessing the database. I have a collection called Movies and I wanted to edit multiple objects in an array within this collection. This is what the Movie Schema contains in my database:
I wanted to edit multiple objects in the 2D array within seats and to change isReserved to True.
I just used findOne in accessing the data since I still don't know how to update the objects that I want to access.
app.post('/confirm/:movieId/:timeId', (req, res) => {
const movieId = req.params.movieId;
const timeId = req.params.timeId;
const selectedSeats = req.body;
// console.log("in confirm DB ");
// console.log(selectedSeats);
let getSeats;
let getTimeSlots;
const length_timeId = timeId.length;
Movies.findOne({ movieId }, (err, movie) => {
console.log("INSIDE");
getTimeSlots = movie['timeslots'];
let index = timeId.substring(1, length_timeId);
//get the seats
getSeats = getTimeSlots[parseInt(index)-1];
//loop through seats
console.log("PRINTING GET SEATS");
console.log(getSeats);
for(var i=0; i<selectedSeats.length; i++) {
let row = parseInt(selectedSeats[i] / 5);
let id = selectedSeats[i] % 5;
console.log(getSeats["seats"][row][id]);
}
})
})
I already accessed the objects that I want to edit as that code displays this on my terminal:
Would really appreciate some tips on how to update the isReserved status. Thanks!
Do you specify the timeslot and seat by an id or by the index within the array? If you use the index then solution is quite simple
const key = "timeslots." + req.params.timeId + ".seats." + req.body + ".isReserved";
var upd = {};
upd[key] = true;
db.Movies.updateOne({ movieId: req.params.movieId }, { $set: upd })
If your code uses the id then you have to work with array filters, see Update Nested Arrays in Conjunction with $[], so similar to this
db.Movies.updateOne(
{ movieId: req.params.movieId },
{ $set: { "timeslots.$[slot].seats.$[seat].isReserved": true } },
{ arrayFilters: [ { "slot.id": req.params.timeId } , { "seat.id": req.body } ] }
)
I have a model in Firebase, who is saved like this:
Im fetching the data in my componentDidMount like this:
fetchMatches = async () => {
const { firebaseApp, auth, pool } = this.props;
await firebaseApp.database()
.ref(`/pools/${pool.key}/users/${auth.uid}/`)
.once('value')
.then(snapshot =>{
this.setState({matches:snapshot.val()})
})
}
The problem is, that my state, becomes an object: Not an Array, not a list.
How can I read this data, in a proper way that I can filter it based on an atribute.
When I try to do
let matches = this.state.matches;
for (let index = 0; index < matches.length; index++) {
const element = matches[index];
console.log(element);
}
It not works.
When I try to use a this.state.matches.map() they say that is not a function. And it really isnt as on my debugger this.state.matches is an OBJECT.
What Im doing wrong here?
When you are fetching data with the once function it returns an object of that specific ref, in that case, it will return this ${auth.uid} data as an object.
So you might want to change your ref a little bit to: ref(/pools/${pool.key}/users/${auth.uid}/matches),
then to loop through the matches children, according to the firebase documentation https://firebase.google.com/docs/database/web/lists-of-data#listen_for_value_events
await firebaseApp.database()
.ref(`/pools/${pool.key}/users/${auth.uid}/matches`)
.once('value')
.then(snapshot =>{
snapshot.forEach(function(childSnapshot) {
var childKey = childSnapshot.key;
var childData = childSnapshot.val();
// ...
});
})
I am looking to get the the key from a firebase push command when using cloud functions.
const params = {
date: Date.now(),
movie,
movieId: movie.id,
userId: user.uid,
group: 'home',
type: 'watched'
};
const pastRef = event.data.adminRef.root.child(`pastActivity/${user.uid}`);
var newPostRef = pastRef.push().set(params);
var postId = newPostRef.key;
console.log(postId); //undefined
The postId however comes back as undefined. Have try a few other suggested methods without any results.
Reference.set() returns a void promise that resolves when the write operation completes. You can't get the key of it. Instead, split the push() and set(...) into separate statements, so that you can capture the reference
var newPostRef = pastRef.push();
newPostRef.set(params);
var postId = newPostRef.key;
console.log(postId); //undefined
A shorter version can be used if you don't need the newPostRef variable
//var newPostRef = pastRef.push().set(params);
//var postId = newPostRef.key;
const newPostRefKey = pastRef.push(params).key
//this pushes the data and returns the key
I need to create a new array from iterating mongodb result. This is my code.
const result = await this.collection.find({
referenceIds: {
$in: [referenceId]
}
});
var profiles = [];
result.forEach(row => {
var profile = new HorseProfileModel(row);
profiles.push(profile);
console.log(profiles); //1st log
});
console.log(profiles); //2nd log
I can see update of profiles array in 1st log. But 2nd log print only empty array.
Why i couldn't push item to array?
Update
I think this is not related to promises. HorseProfileModel class is simply format the code.
const uuid = require("uuid");
class HorseProfileModel {
constructor(json, referenceId) {
this.id = json.id || uuid.v4();
this.referenceIds = json.referenceIds || [referenceId];
this.name = json.name;
this.nickName = json.nickName;
this.gender = json.gender;
this.yearOfBirth = json.yearOfBirth;
this.relations = json.relations;
this.location = json.location;
this.profilePicture = json.profilePicture;
this.horseCategory = json.horseCategory;
this.followers = json.followers || [];
}
}
module.exports = HorseProfileModel;
await this.collection.find(...)
that returns an array of the found data right? Nope, that would be to easy. find immeadiately returns a Cursor. Calling forEach onto that does not call the sync Array.forEach but rather Cursor.forEach which is async and weve got a race problem. The solution would be promisifying the cursor to its result:
const result = await this.collection.find(...).toArray();
Reference
I'm working with Firebase realtime database and I want to retrieve an array data:
Data:
And my function:
function traerUsuarios(firebase)
{
var ref = firebase.database().ref().child('/Usuario');
console.log(ref)
ref.once('value', function (snap) {
snap.forEach(function (item) {
var itemVal = item.val();
console.log(itemVal);
});
});
}
But the result:
Show me object but no de for of the items
What im doing wrong?
Each item in your for loop are the children of Usario. Each of these children (from your picture 056BN.., CQL.., and E4ll) have an object as their value (hence why they have a + next to them in the database).
So when you say item.val() you're getting the value of each one of those children, which is their corresponding object (The data you see when you click the + in the database.
Thanks to #MarksCode , I fixed the function with data refs:
function traerUsuarios(firebase) { var key;
var starCountRef;
var usuarios=new Array();
// var ref = firebase.database().ref().child('/Usuario');
var query = firebase.database().ref("/Usuario").orderByKey();
query.once("value")
.then(function (snapshot) {
snapshot.forEach(function (childSnapshot) {
// key will be "ada" the first time and "alan" the second time
key = childSnapshot.key;
starCountRef = firebase.database().ref("/Usuario/"+key);
starCountRef.on('value', function (snapshot) {
console.log(snapshot.val());
usuarios.push([key,snapshot.val()]);
});
});
}); }
And the result show me the values: