Is there a way to populate students ?
"cohortStudents": {
"cohort-id-4": {
"cohortId": "cohort-id-4",
"instructorId": "CZVLBcZ7lQe2OUcHdDLjW4OVFaB2",
"students": {
"student-id-1": true,
"student-id-2": true,
"student-id-3": true
}
}
}
So basically i can get data from cohortStudents by
https://[projectname].firebaseio.com/cohortStudents.json?orderBy="cohortId"&equalTo="cohort-id-4"
And i will get object but students: {} will have still student-id-1 etc
Is there a way to get data look like students: { student-id-1: { name: '', email: '' } }
Hope your help
Firebase Database queries read child nodes from a single location only. There is no support for server-side joins.
To get the users that are referenced from students you will have to do a client-side join: loading each user individually.
I highly recommend using a Firebase SDK to do this, since it is optimized for this type of use-case. See my answer to this question for more.
Related
i am getting an error of
Using an unspecified index. Your data will be downloaded and filtered on the client. Consider adding ".indexOn": "WkJymEhTtvgtIzQZZxs3VUTbmLh2quan" at /Products to your security rules for better performance.
this is my code:
firebase.database().ref("Products").orderByChild(user.uid + "quan").startAt(0).on('value', function (s) {
var cartNum = 0;
s.forEach(function (d) {
console.log(d.child(user.uid + "quan").val());
cartNum += d.child(user.uid + "quan").val();
});
$("#cartCount").text(cartNum);
});
am trying to query products that has user.uid+ 'quan' in my firebase database
and this is the structure of my JSON ---->>>
many thanks if someone can help me out
As described in the documentation on indexing data and in the error message, you will need to add an index to the Firebase rules for your database in the console:
{
"rules": {
"Products": {
".indexOn": "WkJymEhTtvgtIzQZZxs3VUTbmLh2quan"
}
}
}
This will solve the error message for the current user. The problem is that you will need to declare such an index explicitly for each UID, which is not feasible unless you have a specific set of users in mind.
The underlying problem is that your current data structure makes it easy to find a user for a given product, but it does not make it easy to find the products for a specific user. To allow the latter use-case, you'll want to add an additional data structure for that inverted mapping, sometimes referred to as a reverse or inverted index:
"Users": {
"uid1": {
"productId1": true,
"productId2": true
},
"uid2": {
"productId3": true,
"productId4": true
}
}
While this duplicates some data, it allows you to look up the related data in both directions. This type of data duplication to allow use-cases is quite common in NoSQL databases.
Also see:
Many to Many relationship in Firebase
Firebase Query Double Nested
Firebase query if child of child contains a value
I have a nested firebase database with a structure like this:
posts: {
0: {
title: "...",
content: '...',
comments: [{
by: "someone"
}, {
by: "anotherone"
}]
},
1: {
...
}
}
Now I want to get the first comments on each post so I tried
firebase.database().ref('/posts/{postId}/comments/0').once('value',function(snapshot){
snapshot.forEach(function(child){ console.log(child.val());});
})
But don't know why the only thing I got in the console is false. So are there anyone knows what's wrong or is it impossible to query like that?
The Firebase Database SDKs will also read entire nodes. It is not possible to retrieve a subset of a node's data or to get just the keys.
To get the first comment of each post, you must know the key of each post already. Since you can't read just the keys of the posts, this means that you must read all data to get just the first comment of each post:
firebase.database().ref('/posts').once('value',function(snapshot){
snapshot.forEach(function(child){
console.log(child.val().comments[0]);
});
})
While this gives the result you need, it is quite wasteful in bandwidth: the client is ready way more data than you need. As usual in NoSQL databases, a better solution may require you to change your data model to fit your use-case. For example: consider storing the latest comment for each post in a separate top-level list:
latest-comments: {
0: {
by: "someone"
},
1: {
...
}
}
You will need to update this list (in addition to your original comments list) whenever a new comment is posted. But in return, reading the latest comment for each post is now very cheap.
In my user collection, I have an object that contains an array of contacts.
The object definition is below.
How can this entire object, with the full array of contacts, be written to the user database in Meteor from the server, ideally in a single command?
I have spent considerable time reading the mongo docs and meteor docs, but can't get this to work.
I have also tried a large number of different commands and approaches using both the whole object and iterating through the component parts to try to achieve this, unsuccessfully. Here is an (unsuccessful) example that attempts to write the entire contacts object using $set:
Meteor.users.update({ _id: this.userId }, {$set: { 'Contacts': contacts}});
Thank you.
Object definition (this is a field within the user collection):
"Contacts" : {
"contactInfo" : [
{
"phoneMobile" : "1234567890",
"lastName" : "Johnny"
"firstName" : "Appleseed"
}
]
}
This update should absolutely work. What I suspect is happening is that you're not publishing the Contacts data back to the client because Meteor doesn't publish every key in the current user document automatically. So your update is working and saving data to mongo but you're not seeing it back on the client. You can check this by doing meteor mongo on the command line then inspecting the user document in question.
Try:
server:
Meteor.publish('me',function(){
if (this.userId) return Meteor.users.find(this.userId, { fields: { profile: 1, Contacts: 1 }});
this.ready();
});
client:
Meteor.subscribe('me');
The command above is correct. The issue is schema verification. Simple Schema was defeating the ability to write to the database while running 'in the background'. It doesn't produce an error, it just fails to produce the expected outcome.
I'm developing and app with Sails.js and using Waterline orm for db. I'm developing functionality for users to do friend requests and other similar requests to each other. I have following URequest model for that:
module.exports = {
attributes: {
owner: {
model: 'Person'
},
people: {
collection: 'Person'
},
answers: {
collection: 'URequestAnswer'
},
action: {
type: 'json' //TODO: Consider alternative more schema consistent approach.
}
}
};
Basically owner is association to Person who made the request and people is one-to-many association to all Persons who the request is directed. So far fine.
Now I want to have a controller which returns all requests where certain user is involved in meaning all requests where user is either in owner field or in people. How I do query like "give me all rows where there is association to person P" ? In other words how I ca know which URequest models have association to a certain Person?
I tried something like this:
getRequests: function (req, res) {
var personId = req.param('personId');
URequest.find().where({
or: [
{people: [personId]}, //TODO: This is not correct
{owner: personId}
]
}).populateAll().then(function(results) {
res.json(results);
});
},
So I know how to do the "or" part but how do I check if the personId is in people? I know I should somehow be able to look into join-table but I have no idea how and couldn't find much from Waterline docs relating to my situation. Also, I'm trying to keep this db-agnostic, though atm I'm using MongoDB but might use Postgres later.
I have to be honest this is a tricky one, and, as far as I know what you are trying to do is not possible using Waterline so your options are to write a native query using query( ) if you are using a sql based adapter or native otherwise, or try doing some manual filtering. Manual filtering would depend on how large of a dataset you are dealing with.
My mind immediately goes to reworking your data model a bit, maybe instead of a collection you have a table that stores associations. Something like this:
module.exports = {
attributes: {
owner: {
model: 'URequest'
},
person: {
model: 'Person'
}
}
Using the sailsjs model methods (like beforeCreate) you could auto create these associations as needed.
Good Luck, I hope you get it working!
I'm new to Emberjs, and I'm trying to get my head around how to get data out of my model.
Here's the data structure as its being returned from my server
candidate: {
image: [image],
user: {
name: [User Name]
},
agent: {
phone: [phone]
team: {
name: [Team Name]
}
user: {
name: [User Name]
}
}
}
I cant get ember to recognize any associations more than one level deep.
heres my candidate controller
App.CandidateController = Ember.ObjectController.extend({
location: function() {
var address = this.get('address');
var city = this.get('city');
var state = this.get('state');
var zip = this.get('zip');
return address + ' ' + city + ' ' + state + ', ' + zip;
}.property('address', 'city', 'state', 'zip')
});
App.CandidateSerializer = DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
attrs: {
agent: {embedded: 'always'},
user: {embedded: 'always'}
}
});
This allows me to get one level deep, but I need two or three levels of association.
Is there a different way to go about it?
I thought organizing everything on the server the way I want it displayed, and just returning the data as its supposed to be rendered to ember, but I have a feeling I'll run into problems when trying to update the models.
Any help is appreciated.
/****** UPDATE *******/
I have refactored my code and I am now returning data from the serializer like this:
{
candidate: {
// relevant fields
},
agent: {
//relevant fields
},
team: {
// relevant fields
}
user: [
{ // candidate user fields },
{ // agent user fields }
]
};
However, data is still not available in my template. In the Ember chrome extension, in the data tab, I get
candidate: (1)
agent: (0)
team: (0)
user (2)
I can see candidate and user data, but not agent or team data. In my candidate model, I have:
App.Candidate = DS.Model.extend({
// other fields
user_id: DS.attr('number'),
agent_id: DS.attr('number'),
user: DS.belongsTo('user'),
agent: DS.belongsTo('agent')
});
It doesn't seem like the belongsTo association actually does anything.
So the first issue is that I'm not getting the correct data, the second issue, and the one that makes me think I am going about this incorrectly, is that I have two users information that I need to display in the template. The first is user information associated with the candidate, and the second is user information that is associated with the agent. Both data need to appear in the same template. Since there is no hierarchy to the data, how would the template know which user info to display in each location?
Again, I think Im thinking about this whole thing incorrectly.
Thanks for your help.
Ember data expects models in a JSON response to be flat, and it's the job of the Serializer to transform your server response into that format. Associations usually are done by ids. The second level is not working because Ember needs to turn each level into an Ember.Object in order to observe property changes.
It might help to look over the JSON conventions portion of the guides. You can also plug your models into the ember data model maker and see what your responses should look like. Finally, make sure you're using the ember-inspector Chrome extension. When I am debugging ember-data related issues, it's usually easiest to just stop after the model hook returns, look in the inspector's store tab, and examine what data has been loaded.