I have a backend on Parse.com. I am trying to get a value from a User object in javascript cloud code, but it is not working. Let's say I am trying to get the email.
Here is the cloud code that retrieves a User Object...
var printUser = function(){
var query = new Parse.Query(Parse.User);
query.get( "2FSYI1hoJ8");
query.find({
success: function(result) {
console.log(result);
}
});
};
and here is the result of that search...
I2014-03-07T22:43:21.894Z]
[{"email":"a#a.com","phoneVerified":true,"randomNumber":99862,"toPhone":"+13035551212","username":"a","objectId":"2FSYI1hoJ8","createdAt":"2014-03-02T21:07:02.192Z","updatedAt":"2014-03-07T22:43:13.103Z","__type":"Object","className":"_User"}]
So I know the search works. I tried using 'result.get("email")', 'result.email', 'result("email")' and any variation I could find in their documentation to get the email value, but nothing works.
The error codes vary based on what is being called, so I will spare you that.
What am I missing?
You have an array of objects (with only one element), not a standalone object. The first element in your array is your result object:
result[0].email
will get you the email property of that object.
Related
I am new in database systems and what I am trying to do is to check whether the e-mail entered by the user during login exists in the database or not. I use Firebase Databse. So, the code I have written is this:
function login(){
var e_mail = document.getElementById("e-mail").value;
rootRef = firebase.database().ref();
rootRef.orderByChild("E_mail").on("child_added", function(snapshot){
lst.push(snapshot.val().E_mail);
//console.log(lst);
})
console.log(lst);
}
let lst = [];
login_btn.onclick = function() {login()};
I want to fetch all e-mails from the database, add them in the list and then loop through that list. Maybe this is not the best way, but that's what I'm working on. I could also just say if (snapshot.val().E_mail == e_mail){alert("there is such a user");}but the problem I have encountered and want to deal with is not that, it's the "callback" function inside login function. When I console the list in the outer function it shows an empty list as it does not run the inner function until it is done with the outer one. I understand this. But how can I avoid or fix this. I want to get the full list of e-mails to be able to loop through it then. Also, I don't know how to end the "loop" in Firebase, because it is sort of looping when it gets the e-mails. So I would like to stop at the moment when it finds a matching e-mail.
You're downloading all users to see if one name exists already. That is a waste of bandwidth.
Instead you should use a query to match the email you're looking for, and only read that node:
rootRef.orderByChild("E_mail").equalTo(e_mail).once("value", function(snapshot){
if (snapshot.exists()) {
// A node with the requested email already exists
}
})
In general, if you need to process all nodes, you'll want to use a value event, which executes for all matching nodes at once. So to get all users from the database, add them to a list, and then do something with that list:
rootRef.orderByChild("E_mail").once("value", function(snapshot){
var list = [];
snapshot.forEach(function(childSnapshot) {
list.push(childSnapshot.val());
});
console.log(list); // this will display the populated array
})
Note that you won't be able to access the list outside of the callback. Even if you declare the variable outside of the callback, it will only be properly populated inside the callback. See Xufox' comment for a link explaining why that is.
Problem
In a social media app I am making with react native and firebase, I am trying to grab the number of comments a post has using the snapshot function of a variable I have saved on my servers, then I am going to add one to this variable when a user adds a new comment. My code to do so is right here:
firebase.database().ref('posts').child(this.state.passKey).update({
comments: firebase.database().ref('posts/'+this.state.passKey).child('comments').snapshot.val() + 1
})
When I actually run this code, I get an error saying:
Reference.child failed: First argument was an invalid path = "undefined".
Paths must be non-empty strings and can't contain ".","#","$","[", or "["
At first I thought this might be that the "this.state.passKey" wasn't actually passing the key, but putting in a key I copied from the server didn't fix the problem.
My Server
-
To get the comments of particular post you should do like this
let postId='someId'
postRef=`/posts/${postId}`
firebase.database().ref(postRef).once("value", dataSnapshot => {
comment=dataSnapshot.val().comments
});
It looks like you're expecting this bit of code to query the database:
firebase.database().ref('posts/'+this.state.passKey).child('comments').snapshot.val() + 1
Unfortunately, it doesn't work that way. There's no snapshot property on a database Reference object returned by child() or ref().
Instead, you'll need to query the database at that reference, then when you're called back with its value, you can apply it elsewhere.
var ref = firebase.database().ref('posts/'+this.state.passKey+'/comments')
ref.once('value', function(snapshot) {
// use the snapshot here
})
I am making an express app with Parse. In my cloud code, I am trying to get an attribute of the current user, but it is returning me undefined. My code looks like following:
app.get('/home/subscriptions',function(req,res){
Parse.Cloud.useMasterKey();
var user = Parse.User.current();
var ifstud = user.get("isStudent");
console.log('student: ' + ifstud); // undefined
console.log('id: ' + user.id); // OK. works fine.
}
I am able to retrieve the id of the user as above but not able to call the get method on user. In their API reference, they have mentioned that Parse.User.current() returns a Parse.Object, so I think in user I have _User object and I should be able to call all methods supported by a Parse.Object.
What might be the issue here?
Thanks
I figured it out and putting this answer for future reference to users who visit this question.
The Parse.User.current() returns only a pointer to the user and not the complete user object. To get access to all fields of the user, fetch the entire object using the fetch method.
var fullUser;
Parse.User.current.fetch().then(user){
fullUser = user;
}).then(function(){
// Place your code here
});
I think it should be: var ifstud = Parse.User.get("isStudent");
So I'm trying to go through one Firebase database to find entries in the database matching a criteria. Therefore I'm using the deferred object of jQuery to handle the database calls.
Once I get a return value from this first database I want to get the user info from a second database for each of those values in the first db. Then the results are added to a JSON array
so its:
<search for value, find one>
<<<search other db for oher info>>>
<continue search for outer value>
But this only returns one value - although everything else is running fine (and the console logs all the info correct).
Here's the code:
function find(searchLocation, profileID) {
var requestUserData = {
data: []
};
var def = $.Deferred();
//This will be executed as long as there are elements in the database that match the criteria and that haven't been loaded yet (so it's a simple loop)
Ref.orderByChild("location").equalTo(searchLocation).on("child_added", function(snapshot) {
def.ressolve(snapshot.val().ID);
});
return def.promise();
};
I hope you guys have any ideas on what to do or how I could solve this. Thanks in advance!
Edit: upon further testing I discovered that this problem already exists in the outer loop - so only the first value is being returned. I think this is related to the posission of the resolve() method but I didn't find a posibility on how to change this behaviour.
Firebase is a real-time database. The events stream as changes occur at the server. You're attempting to take this real-time model and force it into CRUD strategy and do a GET operation on the data. A better solution would be to simply update the values in real-time as they are modified.
See AngularFire, ReactFire, or BackboneFire for an example of how you can do this with your favorite bindings framework.
To directly answer the question, if you want to retrieve a static snapshot of the data, you want to use once() callback with a value event, not a real-time stream from child_added:
Ref.orderByChild("location").equalTo(searchLocation).once("value", function(snapshot) {
def.resolve(snapshot.val());
});
I have a Player class. Players can have x number of Trophies. I have the Player objectId and need to get a list of all of their Trophies.
In the Parse.com data browser, the Player object has a column labeled:
trophies Relation<Trophy>
(view Relations)
This seems like it should be so simple but I'm having issues with it.
I have the ParseObject 'player' in memory:
var query = new Parse.Query("Trophy");
query.equalTo("trophies", player);
query.find({
/throws an error- find field has invalid type array.
I've also tried relational Queries:
var relation = new Parse.Relation(player, "trophies");
relation.query().find({
//also throws an error- something about a Substring being required.
This has to be a completely common task, but I can't figure out the proper way to do this.
Anyone know how to do this in Javscript CloudCode?
Many thanks!
EDIT--
I can do relational queries on the user fine:
var user = Parse.User.current();
var relation = user.relation("trophies");
relation.query().find({
I don't understand why this very same bit of code breaks if I'm using a non-user object.
I finally sorted this out, though there is a caveat that makes this work differently than the documentation would indicate.
//Assuming we have 'player', an object of Class 'Player'.
var r = player.relation("trophies");
r.query().find({
success: function(trophies){
response.success(trophies); //list of trophies pointed to by that player's "trophies" column.
},
error: function(error){
response.error(error);
}
})
The caveat: You must have a 'full' player object in memory for this to work. You can't save a player object, grab the object from the success callback and have this work. Some reason, the object that is returned in the success handler is appears to be an incomplete Parse.Object, and is missing some of the methods required to do this.
Another stumbling block about the Parse.com Javascript SDK- A query that finds nothing is still considered successful. So every time you query for something, you must check the length of the response for greater than 0, because the successful query could have returned nothing.
This is what worked for me:
var Comment = Parse.Object.extend("Comment");
var commentsQuery = new Parse.Query(Comment);
commentsQuery.equalTo("parent", video);//for the given 'video' instance, find its children (comments)
commentsQuery.descending("createdAt");
return commentsQuery.find();
Note: of course, video is an instance of the Video class. And returning find() means I'll have to handle the 'promise' in whatever function calls this one.
And here is another function coming from the other angle:
getRecentCommentsOfAllVideos: function(limit) {
var Comment = Parse.Object.extend("Comment");
var commentsQuery = new Parse.Query(Comment);
commentsQuery.descending("createdAt");
commentsQuery.limit(limit);
commentsQuery.include("parent");//this enables the details of the comment's associated video to be available in the result
return commentsQuery.find();
}
(Be sure to read https://parse.com/docs/js_guide and search for the line that says "Include the post data with each comment".)
I also looked at these materials; maybe they'll help you (though they weren't much help for me):
https://parse.com/questions/how-to-retrieve-parent-objects-with-their-children-in-one-call-javascript-api
http://blog.parse.com/2011/12/06/queries-for-relational-data/