Query orderByChild in Firebase Realtime Database not working? - javascript

I've seen many posts and solutions that are precisely what I need but when I implement it it doesn't work. I'm using the Firebase Realtime Database and I'm trying to search all "Name" children for a specific name. In this example I added the strings directly, but I'll be using a variable based on user input in the future. Here is my database structure as I see it in firebase:
{
"kjienk24dfwefn" : {
"FriendID" : "fr1959l9591i4925a",
"Name" : "Test Dummy2",
"email": "something#gmail.com",
"Status" : "InGame"
},
"kjienk24kdfiwne" : {
"FriendID" : "fr2812p8092m3604l",
"Name" : "Test Dummy",
"email":"some#something.com"
"Status" : "Online"
},
"kjienk24udfjjo" : {
"FriendID" : "fr7605h9204f8099g",
"Name" : "Test Dummy3",
"email": "fake#fakeemail.com"
"Status" : "Offline"
}
}
And here is the code I'm using to query the "Name" (usersRef points to "firebase.database().ref()"). I've seen lots of examples of this online and I'm not sure what I'm doing incorrectly.
usersRef.orderByChild("Name").equalTo("Test Dummy").on("value", function(snapshot) {
//This is where I expect to see Test Dummy on the console.
console.log(snapshot.val())
});
EDIT: Here is the initialization of usersRef. Haven't had any problems reading and writing to the database. Standard firebaseConfig.:
const fbApp = firebase.initializeApp(firebaseConfig);
const db2 = fbApp.database("https://firebasedatabaseurl.com/")
const usersRef = db2.ref();
Test with parent node:
Thanks all in advance!

You want to load data from the users node, but that is currently not mentioned anywhere in your code. So Firebase is querying the root of your database, and the child nodes under there (like users) don't have a Name property, so you get no results.
const usersRef = db2.ref().child("users");
Or:
const usersRef = db2.ref("users");

Related

Dialogflow and Firebase - Iterate list of data

Making a chatbot that recommends a movie based on genre and other factors. Trying to iterate through an object retrieved from a firebase realtime database in DialogFlow. I'm using forEach but when triggered it displays "Not Available".
Preferably, the function would display a random item from the list but I have not reached that part yet - any advice on this too would be appreciated.
Below is my code.
function displayData(agent) {
return ref.orderByChild("genre1").equalTo("Comedy").on("child_added", function(snapshot) {
let obj = {};
obj = snapshot.val();
obj.forEach(function(childSnapshot) {
var childData = childSnapshot.val();
agent.add(childData.name);
});
});
}
Below is a sample database
{
"movies" : {
"movie1" : {
"genre1" : "Sci-Fi",
"genre2" : "Horror",
"name" : "Alien",
"rating" : 84,
"year" : 1979
},
"movie2" : {
"genre1" : "Comedy",
"genre2" : "Parody",
"name" : "Airplane",
"rating" : 97,
"year" : 1980
},
"movie3" : {
"genre1" : "Comedy",
"genre2" : "Teen",
"name" : "Superbad",
"rating" : 88,
"year" : 2007
}
}
}
The base problem is that the Dialogflow library requires you to return a Promise, however you're using the callback version of the call instead of the Promise version of the call. You need to change this to something more like
function displayData(agent) {
return ref.orderByChild("genre1").equalTo("Comedy").on("child_added")
.then( snapshot => {
// Do something with the snapshot
});
}
(You probably also want to use once("value") instead of on("child_added"), since you don't need updates to be sent in realtime.)
While the forEach() is probably working correctly, there is a minor problem that not all agents will return all the text that has been .add()ed. So you probably only want to call .add() once.
Since you really only want once of these children, picked randomly, you can just treat this as a JavaScript object if you have enough memory. So you could just get the keys with Object.keys(obj), pick one of the keys by random, and then get the full value of the result.

Retrieve data from mongodb and display to terminal

Background
I just started learning how to use node.js and mongodb.
iv been able to create a db and connect to it / write a collection using the code below
var url = "localhost:27017/TheDatabase";
var collections = ["Location"];
var mongojs = require("mongojs")
var db = mongojs(url, collections);
var object = {
"place" : {
"address" : "123 road",
"code" : "ABC CDE",
"letters" : "AA",
"coord" : [ 99.55, -20.5 ]
},
"keyword1" : "World",
"keyword2" : "Biomech",
"keyword3" : "Spotify",
"_id" : "1"
}
db.Location.save(object);
The Problem
I was unable to successfully retrieve the data from this database/collection.
What i want to do is just retrieve "object" from db and display it to terminal to see i accomplished the store/retrieve correctly.
What i'v tried
I'v opened mongo.exe and tried running
use TheDatabase
show collections
db.Location.find()
and was able to see the data. I'm not sure how i implement this in my node.js application.
Edit
db.Location.find(function (err, docs) {
console.log(docs);// docs is an array of all the documents in mycollection
})

Displaying User Specific Data from Firebase with ReactFire or Re-base

I am using Firebase as my DB with React on the front-end. I am trying to display user specific data (notes) and display it. I have asked similar questions on SO, but I think they were too open ended, so this is more specific:
I have organized my data in accordance to Firebase's denormalized suggestions. Here's a look at how the data is structured:
"notes" : {
"n1" : {
"note" : "[noteData]",
"created_at" : "[date]",
"updated_at" : "[date]",
}
},
"users" : {
"userOne" : {
"name" : "[userName]",
"notes" : {
"n1" : true
}
}
}
Thanks to the other commenters, I have been able to use either ReactFire and Tyler McGinnis's Re-base to grab each user's list of note keys, and create a note object in state. This looks like so:
ReactFire
firebaseRef.child('users/' + authData.uid + '/notes').orderByChild('date_updated').on("child_added", function(noteKeySnapshot) {
ref = firebaseRef.child('notes/' + noteKeySnapshot.key());
this.bindAsObject(ref, noteKeySnapshot.key());
}.bind(this));
Re-base
firebaseRef.child('users/' + authData.uid + '/notes').orderByChild('date_updated').on("child_added", function(noteKeySnapshot) {
base.syncState('notes/' + noteKeySnapshot.key(), {
context: this,
state: noteKeySnapshot.key(),
asArray: false,
});
}.bind(this));
Both of these solutions add each note object to the top of the this.state tree. This makes it difficult to access the notes as a group. I would like to add each note object to an array, something like this.state.notes.
How can I use either ReactFire or Re-base to add each note object into an array in this.state?
I'm open to other solutions on how these objects can be accessed in this.state.
If I am not mistaken you have to set it where you putting the snapshot.
in the examples in the Github,
componentDidMount(){
base.syncState(`notes`, {
context: this,
state: 'notes', //Changes this to whatever you want as inner state.
asArray: true
});
}

Firebase - Retrieving data from pushed items

I'm stuck on this issue of how to retrieve pushed data from firebase. I've got it set up with authentication and I had two users push a little bit of data:
{
"deck" : {
"-JkpwAnieKjQVsdtPD4m" : {
"deckName" : "Deck 1",
"color" : "Red",
"user" : "simplelogin:1"
},
"-Jkq4unexm-qwhO_U2YO" : {
"deckName" : "Deck 2",
"color" : "Blue",
"user" : "simplelogin:1"
},
"-Jkq5-II1q5yM6w3ytmG" : {
"deckName" : "Deck 3",
"color" : "Green",
"user" : "simplelogin:6"
}
}
}
Then I run:
deckRef.once('value', function(dataSnapshot) {
console.log(dataSnapshot.val());
});
Which returns the 3 pushed with their keys generated by push().
It seems there there a way with firebase to say retrieve all color entries that are made by "simplelogin:1" (so Red and Blue) but I just can't figure it out.
You're probably looking for Firebase's queries, which allow you to:
deckRef.orderByChild('user').equalTo('simplelogin:1').on(...
Don't forget to add user to the .indexOn in your security rules.
See:
Firebase documentation on queries
Firebase documentation on indexing data
query your data like this
deckRef.orderByKey().once('child_added', function(dataSnapshot) {
console.log(dataSnapshot.val());
});
Note: orderByKey() works with child_added eventType
Reference

Meteor Mongo not working but standalone MongoDB is

I have the following document
{
"_id" : ObjectId("5464e68481f8252e74f6e0ef"),
"message" : "Hello World!",
"timestamp" : ISODate("2014-11-13T17:12:36.547Z"),
"sender" : "D3EkLv8vatX3xfCGE",
"receiver" : [
{
"id" : "YzhZchz4AwCAd3q2R",
"seen" : false
},
{
"id" : "sm2W28EKYmHz29Aoj",
"seen" : false
}
],
"saved" : false
}
That's the basic structure. Now I want to get all the documents that have the current user's ID. The id can be in the sender field or one of the object in the receiver array. This works fine:
db.messages.find({ sender: "D3EkLv8vatX3xfCGE" })
But the following query doesn't work on the Meteor Mongo instance but does so in Mongo 2.6:
db.messages.find({ receiver: {id: "YzhZchz4AwCAd3q2R"} })
Is there any way I can get this to work. Also, the above query works on Minimongo but doesn't work on Meteor's bundled mongo(meteor mongo) which is currently at v2.4.9.
On mongo shell this query seems to work:
db.messages.find({ "receiver.id": "YzhZchz4AwCAd3q2R"} )
You can find all of the documents were a particular user is a receiver using receiver.id in your selector like so:
Messages.find({'receiver.id': 'YzhZchz4AwCAd3q2R'})
If you wanted to find all documents where a particular user was either a receiver or a sender you could do this:
var id = 'YzhZchz4AwCAd3q2R';
Messages.find({$or: [{'receiver.id': id}, {sender: id}]});

Categories