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.
Related
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'm trying to create a database with "users" and their data in it. Strangely it doesn't put() new variables in it when I try to for the third time. To do all this I create a local database dblocal and replicate this DB to the remote db called dbremote. At first I create a document with one variable.
function newuser() {
if (window.document.consent_form.consent_to_share.value) {
var id = "p" + Date.now() + "-" + Math.floor(Math.random() * 10000);
var dblocal = new PouchDB(id);
var consenttoshare = window.document.consent_form.consent_to_share.value;
document.cookie = id;
var dbremote = 'http://localhost:5984/experiment';
dblocal.put({
_id: id,
consent: consenttoshare
});
dblocal.replicate.to(dbremote, {live: true});
}
}
This all worked well, in another js file I'm trying to add a variable to the same document by executing the following function putdb(). Im doing this in the following way (as said in their documentation is the right way):
function putdb () {
if (document.cookie){
var id = document.cookie;
var loggedin = "True";
var dblocal = new PouchDB(id);
dblocal.get(id).then(function (doc) {
doc.loggedin = loggedin;
return dblocal.put(doc);
}).then(function () {
return dblocal.get(id);
}).then(function (doc) {
console.log(doc);
var dbremote = 'http://localhost:5984/experiment';
dblocal.replicate.to(dbremote, {live: true});
});
}
}
This succesfully added the variable loggedin to the document as I wanted. However upon trying to add information to this document for the third time (again in another js file), nothing happens. I used exactly the same approach as before but only use different variables.
function putdb (checked) {
if (document.cookie) {
var id = document.cookie;
var checkedlist = [];
for (i = 0; i < checked; i++) {
checkedlist.push($("input[type=checkbox]:checked")[i].value)
}
var playlistname = document.getElementById("playlistname").value;
var dblocal = new PouchDB(id);
dblocal.get(id).then(function (doc) {
doc.checkedlist = checkedlist;
doc.playlistname = playlistname;
return dblocal.put(doc);
}).then(function () {
return dblocal.get(id);
}).then(function (doc) {
console.log(doc);
var dbremote = 'http://localhost:5984/experiment';
dblocal.replicate.to(dbremote, {live: true});
});
}
}
I checked all variables, they are correct.
I tried plain text variables.
The script does run.
I tried to add information to the document the way I did the first time.
None of all this seems to add another variable to the document as I wanted in the last function. I think it has to do with the way pouchDB works which I don't know. help is much appreciated!
There are a number of problems in your code that results in bad usage of PouchDB, and may lead to problems.
First of all, it does not make a lot of sense to give your document the same id as the name of your database. Assuming you want a one database per user approach, there are two approaches you can follow.
Multiple document approach
You can instead make multiple documents within the same database with different id's. For instance, your 'consent' information may be stored like this:
var id = "p" + Date.now() + "-" + Math.floor(Math.random() * 10000);
let dblocal = new PouchDB(id);
document.cookie = id;
let dbremote = 'http://localhost:5984/experiment';
dblocal.put({
_id: "consent",
consent: window.document.consent_form.consent_to_share.value
});
dblocal.replicate.to(dbremote, {live: true});
While your playlist information is stored like this:
dblocal.put({
_id: "playlist",
name: playlistname,
itemsChecked: checkedlist
});
Single-document approach
The second option is to store a single document containing all the information you want to store that is associated to a user. In this approach you will want to fetch the existing document and update it when there is new information. Assuming you named your document global-state (i.e. replace "consent" in the first code snippet with "global-state"), the following code will update a document:
dblocal.get("global-state").then((doc)=>{
doc.loggedIn = true; // or change any other information you want
return dblocal.put(doc);
}).then((response)=>{
//handle response
}).catch((err)=>{
console.log(err);
});
Furthermore, you should only call the
dblocal.replicate.to(dbremote, {live: true});
function once because the 'live' option specifies that future changes will automatically be replicated to the remote database.
I'm trying to set firebase references dynamically. What I know from the doc is firebase set references at the initial state. As long as I try to make it dinamic it give me permission error.
For example I want to get fruit name from the input, so the code:
$('.fruit').click(function(){
var name = $(this).text();
getFuitName(name);
});
function getFruitName(name){
var fruit = firebase.database().ref('fruit/' + name );
fruit.once('value', function(snapshot) {
console.log(snapshot.val().name);
});
}
What should I do? Any special approach to do this?
I found the solution. I've to separated the database references like this:
var database = firebase.database(); // I add this line
$('.fruit').click(function(){
var name = $(this).text();
getFuitName(name);
});
function getFruitName(name){
var fruit = database.ref('fruit/' + name ); //and then modified this line
fruit.once('value', function(snapshot) {
console.log(snapshot.val().name);
});
}
I am new to Firebase, and I am trying to figure out how to retrieve data from my Firebase database. I was able to add to it successfully based on a user's unique id (uid), but now getting data from it seems to be incredibly difficult. I want to grab the first name from the current user ('user' in the following code), but this JavaScript doesn't seem to be working:
var uid = user.uid
firebase.database().ref('users/' + uid).on('value', function(snapshot) {
this.first_name = snapshot.val().first_name;
});
As soon as I make the call to this.first_name, it gives me the following error:
FIREBASE WARNING: Exception was thrown by user callback. TypeError: Cannot set property 'first_name' of null.
In case it helps, my database is structured like this:
{
users: {
"uid1": {
first_name: "John"
},
"uid2": {
first_name: "Sue"
}
}
}
Use var first_name instead of this.first_name. It should work.
var uid = user.uid
firebase.database().ref('users/' + uid).on('value', function(snapshot) {
var first_name = snapshot.val().first_name;
});
The answer above is correct. but, i guess it's more readable if you use child in the query. Both should work.
firebase.database().ref('users').child(uid).on('value', function(snapshot) {
var first_name = snapshot.val().first_name;
});
I'm still struggling to understand how to access Meteor.users as a foreign key from another collection query. I understand that only the current user is published by default so I have a publication on the server as
Meteor.publish('itemOwner', function(userId) {
check(userId, String);
var user = Meteor.users.find({id: userId});
return user;
// return Meteor.users.find({id: userId}, {
// fields: {'profile': 1} });
});
I then have a Deps.autorun on the client..
Deps.autorun(function () {
var itemOwnerId = Session.get("itemOwnerID");
if (itemOwnerId) {
debugger
var ID = Session.get("itemOwnerID");
Meteor.subscribe('itemOwner', Session.get("itemOwnerID"));
}
});
I set the session ID on a modal form load, and display it in the template by calling the ownerProfile helper (or try to)
Template.showQuoteModalInner.helpers({
getQuote: function () {
// Get the quote ID from the session var
var quote = Session.get("quoteID");
if(quote) {
debugger;
var ID = quote.user._id;
Session.set("itemOwnerID", quote.user._id);
return quote;
}
},
ownerProfile: function() {
debugger;
var quote = Session.get("quoteID");
if(quote) {
var ID = quote.user._id;
var theUser = Meteor.users.find({_id: quote.user._id});
return theUser;
};
}
});
Now, I can trace the user ID at each stage and see it getting correctly passed to the autorun and the helpers. If I stop the program at the debugger in the ownerProfile helper and in the console put in Meteor.user.fetch({_id: "the id here"}).fetch() I get the correct user back.. but, in the handler itself the Meteor.users.find returns null??? What am I missing?
Two possibilities I noticed.
First, you are missing an underscore in the find in your publish function.
.find({id: userId}) should be .find({_id: userId}).
But this probably isn't the issue if you are seeing the user (other than the logged in user) in the console.
Second, if you are not seeing the user from your Template.showQuoteModalInner.ownerProfile helper, it is probably because you are returning a find() instead of a findOne().
find() returns a cursor whereas findOne() returns the record. Try findOne() if you want to display that single user's attributes.