I am using angularfire.
I have my node in firebase /texts/ and it loos like that:
{ title: 'title', text: 'long text' }
In my service i want to get just the title because i want to show a list of the titles and i don't want to load the texts at this moment because usually are a very long texts.
My service looks like that:
var ref= new Firebase( FBURL+'/texts' );
var sync = $firebase(ref);
var text = sync.$asArray();
this.getTitle = function(){
var deferred = $q.defer();
var titles = [];
text.$loaded().then(function(data){
lodash.forEach(data, function(item){
titles.push({title: item.title});
});
deferred.resolve(titles);
})
.catch(function(err){
$state.go('login');
deferred.reject(err);
});
return deferred.promise;
};
I have noticed that inside the variable text there are all the objects so i get everything included the text. What i want to to is just a select name from texts :)
Thanks
When you access Firebase through most of its APIs, it will always retrieve complete nodes. So you can not tell it to retrieve only a subset of the properties.
That means that if you really only want the titles, you'll have to model your data differently. Right now you have something like this:
posts
-Jas73489342
title: "how to make a select query using firebase"
text: "...."
-Jasa8324023
title: "bicycling the grand canyon"
text: "..."
Those -J things are the keys that Firebase generates when you call push.
In order to be able to retrieve just the titles, you'll need to make sure that there is a node that contains just the titles. So let's split up our posts into two separate nodes: titles and texts.
titles
-Jas73489342: "how to make a select query using firebase"
-Jasa8324023: "bicycling the grand canyon"
texts
-Jas73489342: "...."
-Jasa8324023: "..."
To add a new post to the above structure, you'd do something like:
var ref = new Firebase(FBURL),
titles = ref.child('titles'),
texts = ref.child('texts'),
item = { title: 'Petroglyphs in Albuquerqe', text: '...' };
var newItemRef = texts.push(item.text);
var key = newItemRef.key();
var newTitleRef = titles.child(key).set(item.title);
So we first add the text of the new post to the texts node and then use the same key to add the title under the titles node.
You could also leave the posts node as is, but add a titles node with just the titles. Either way you'll have a node that represents precisely what you want: a list of titles.
Related
I am storing my data in firebase with update() like so
var newKey = firebase.database().ref().push().key;
var updates = {};
updates['metadata/' + newKey] = {
name: $scope.formData.name,
price: $scope.formData.price
};
updates['realdata/' + newKey] = {
name: $scope.formData.name,
price: $scope.formData.price,
date: $scope.formData.date
};
return firebase.database().ref().update(updates)
.then(function(ref){
console.log("added in fb");
}, function(error){
console.log("error " + error)
});
Now on an other page I am pulling the data out of firebase, but I can't seem to map it to my list in my view.
I tried multiple ways to pull the data out and in both ways I can see the data when logging it to the console.
var dbRef = firebase.database().ref('/metadata');
//Method 1
$scope.list = $firebaseArray(dbRef);
/*
Result here in the console is an array with objects
but when setting this in my list, I get the same amount of items pulled out but they are empty
*/
//Method 2 - I prefer this way as per docs it's a best practice
var loadmetadata = function(data){
console.log(data.val().name); // I get the actual name
$scope.list = data.val().name
};
dbRef.on('child_added', loadmetadata);
dbRef.on('child_changed', loadmetadata);
My view is just a simple
<ion-item ng-repeat="listitem in list">
{{ listItem.name }}
</ion-item>
What am I missing? I prefer the second method, if someone can help me achieve this?
The thing is I've found someone with the same problem here on SO, and he was able to solve it with the methods I have above. Here is the link to the question/answer Firebase 3 get list which contain generated keys to ionic list
The only difference I am seeing is that he's sorting the results, but I don't need that currently.
I've just figured it out! Instead of using $firebaseArray, I need to use the $firebseObject method.
$scope.metadataObj = $firebaseObject(dbRef);
and in my view I can do the following:
<ion-item ng-repeat="(key, value) in metadataObj">{{value.name}}</ion-item>
This method contains all the child methodes too. So no need to listen for them separetely.
I'm using angular-ui-fullcalendar to show and edit events. Users can log in and have unique uid when logged in. I want to use this to distinguish events made by current user from other events. I want to give current user events another backgroundColor.
What is the best way to do this??
I tried several things. My data looks like this:
```
database
bookings
-KWnAYjnYEAeErpvGg0-
end: "2016-11-16T12:00:00"
start: "2016-11-16T10:00:00"
stick: true
title: "Brugernavn Her"
uid: "1f17fc37-2a28-4c24-8526-3882f59849e9"
```
I tried to filter all data with current user uid like this
var ref = firebase.database().ref().child("bookings");
var query = ref.orderByChild("uid").equalTo(currentAuth.uid);
var bookings = $firebaseArray(query);
$scope.eventSources = [bookings];
This doesn't return anything. If I omit the filter in line 2 it returns all bookings as expected. But even if the filter worked it would not solve my problem, because I want to fetch both current user events and all other events. Firebase does not have a "not equal to" filter option...
I tried to loop through each record and compare uids and setting backgroundColor if condition was met:
var ref = firebase.database().ref().child("bookings");
var bookings = $firebaseArray(ref);
bookings.$ref().on("value", function(snapshot) {
var list = snapshot.val();
for (var obj in list) {
if ( !list.hasOwnProperty(obj) ) continue;
var b = list[obj];
if (b.uid === currentAuth.uid) {
b.className = "myBooking";
b.backgroundColor = "red";
}
}
});
$scope.eventSources = [bookings];
But this causes asynchronous problems so the 'bookings' array assigned to $scope.eventSources wasn't modified. I tried to move the $scope.eventSources = [bookings] inside the async code block but FullCalendar apparently can't handle that and renders nothing.
I also tried this but no luck either:
bookings.$loaded()
.then(function(data) {
$scope.eventSources = [data];
})
.catch(function(error) {
console.log("Error:", error);
});
What is the best solution to my problem?
If you're looking to modify the data that is loaded/synchronized from Firebase, you should extend the $firebaseArray service. Doing this through $loaded() is wrong, since that will only trigger for initial data.
See the AngularFire documentation on Extending $firebaseArray and Kato's answer on Joining data between paths based on id using AngularFire for examples.
Scenario is,
Our data on firebase is structured as shown below
Image is based on sample database where post1,post2 under Posts node are randomly generated keys just like "YyhsyyHyzhh-Ke" etc and comment1,comment2 also randomly generated keys.
My problem is that I want to fetch all posts and related comments from firebase and as you can see under post1,there is a comments node which contains keys of comments related to post1 but im unable to get keys of comments so that I can browse to that comment's text
see below code
appMainModule.controller('GetCtrl', ['$scope', '$firebase', function ($scope, $firebase) {
var firebaseObj = new Firebase("FirebaseURL/Posts");
var sync = $firebase(firebaseObj);
$scope.articles=sync.$asArray();
$scope.articles.$loaded(function (data) {
var mainVar ;
for (var i = 0; i < data.length; i++) {
mainVar = data[i];
var commentsWithIds=mainVar.Comments;
//how to fetch keys side of data from commentsWithIds as I dont know rendomly generated keys
}
});
I want get comments keys so that I cloud make URL like this new Firebase("FirebaseURL/Comments"+CommentsAutoGeneratedKey) .
If I understood your question well, you can use Object.keys() method:
var comments = {
"comment1":{
"text":"this is first comment"
},
"comment2":{
"text":"this is 2nd comment"
},
"comment3":{
"text":"this is third comment"
}
};
console.log(Object.keys(comments));
I'm adding a 'new stories' feature to a website for authors to contribute work to. The function below allows stories to be created and added to the author's profile but doesn't auto-add them to a list (ie I have to refresh the browser for this to work. Does anyone know if there is a way to do this (I've tried changing state back to 'authorprofile' but that didn't work).
self.addStory = function() {
var authorId = tokenService.getAuthor()._id;
console.log(authorId);
var data = {
story: self.currentStory,
authorId: authorId
}
Story.save(data, function(story) {
console.log("saving: " + story);
Story.put(data, function(story){
console.log("story added");
})
// auto-add new stories here
$state.go('authorprofile');
})
}
Assuming the list of stories is stored in a 'stories' variable on the scope:
// auto-add new stories here
$scope.stories.push(data);
Add new story into the array using in the success function using push method.
Story.save(data, function(story) {
//Add stories to the array
$scope.stories.push(story);
Story.put(data, function(story){
console.log("story added");
})
// auto-add new stories here
$state.go('authorprofile');
})
I'm learning angularfire and i wonder if i need the whole data from my database (but i want to perform CRUD operations on each "entity") is it better to do this:
var ref = new Firebase(FBURL);
var db = $firebase(ref).$asObject();
db.$loaded(function (db) {
console.log('loaded db is', db);
$scope.categories = db.categories;
$scope.products = db.products;
});
or
var ref = new Firebase(FBURL);
var products = $firebase(ref.child('products')).$asArray();
var categories = $firebase(ref.child('categories')).$asArray();
products.$loaded(function (loadedProducts) {
console.log('loaded products are', loadedProducts);
$scope.products = loadedProducts;
});
products.$loaded(function (loadedCategories) {
console.log('loaded categories are', loadedCategories);
$scope.categories = loadedCategories;
});
Also what is a good approach if i want a sidebar with a list of my categories with every product in the category? How should i join my data? In every category i'm storing a list of products with ids like
category:{
name:"Machines"
products:[alskdjgasld,asldkgjb2k2349,eoilfkasdbf2,21iyebfhsdafas]
}
Then when i want to display the category with the products in my html, what is the best way to join them and to keep them in sync? I mean if the product name changes the change should be reflected in the joined list too, automatically. What is the best approach?
Thanks!