How do you pass a variable limit into a Backbone.Firebase.Collection? - javascript

The firebase documentation here (https://github.com/firebase/backfire#backbonefirebasecollection) mentions that you can apply a limit to a Backbone.Firebase.Collection:
var Messages = Backbone.Firebase.Collection.extend({
firebase: new Firebase("https://<your-firebase>.firebaseio.com").limit(10)
});
I would like to make that limit a variable - so I could sometimes show 10 records from the collection and sometimes 100 (as an example).
Can anyone recommend the best way to achieve this?

Firebase now supports query limits, using limitToFirst or limitToLast
The following code would get the first 2 records.
var ref = new Firebase("https://dinosaur-facts.firebaseio.com/");
ref.orderByChild("height").limitToFirst(2).on("child_added", function(snapshot) {
console.log(snapshot.key());
});
More info in the docs: https://www.firebase.com/docs/web/api/query/limittofirst.html

Related

Have an empty docs in querySnaphsot when trying to get data with firebase

I recently developped a firebase schedule function to retrieve data on every monday.
I tested it during the previous days and it was working correctly. However, this morning, I discovered that my query wasn't able anymore to retrieve data as it used to do. I now have an empty array at QuerySnapshot.docs. You can find my code below:
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();
const db = admin.firestore();
exports.scheduledFunction = functions.pubsub.schedule("0 0 * * 1").onRun(async () => {
console.log("start");
const querySnapshotnext = await db.collection("Next_challenges").orderBy("createdAt").get();
console.log("Let see querySnapshot :", querySnapshotnext); //it works, I can see QuerySnapshot object
console.log("Let see docs :", querySnapshotnext.docs); //have an empty array [] even if it should not, it wasn't empty few days ago
console.log("let see the data of the first doc : ", querySnapshotnext.docs[0].data()); //is of course undefined
return null;
});
You can find my database below with the doc that is normally selected:
The rules of my databases are the following :
I don't really understand why my code isn't working anymore, I think it's certainly related to some parameters stuffs and don't really know how I could debug this by myself so don't hesitate to give me some tips so I can be more autonomous with firebase. Thank you :)
Firestore's documentation has a note that says,
An orderBy() clause also filters for existence of the given field. The result set will not include documents that do not contain the given field.
You have .orderBy("createdAt") in your query but there isn't any createdAt field in the documents (at least the one in screenshot). Did you change your document structure recently that is causing this issue?
Also the Admin SDK bypasses any security rules so I'd recommend setting them to false if you don't need to access data directly from client.

FieldValue.increment does not work but adds "operand"

I'm using a firebase database and a simple function with the new FieldValue.increment to increment a counter but that does not work but adds "operand" field without ever incrementing it.
My function is super simple:
exports.updateCounters = functions.https.onRequest((req, res) => {
// grab the parameters.
const username = req.query.username;
var updateObject = { };
updateObject[username] = admin.firestore.FieldValue.increment(1);
admin.database().ref('counterstest').update(updateObject);
});
When I deploy and call this function I would expect to see
countertest: {
myusername: 1
}
but I see
countertest: {
myusername: {
operand: 1
}
}
instead and operand: 1 never increments even if I call my function multiple times.
Can somebody point out what error I'm making here?
Thank you!
FieldValue.increment() is a feature of Cloud Firestore, but you're apparently trying to apply it to Realtime Database. This is not going to work - they are different databases, and Realtime Database doesn't support atomic increments like this.
What you're actually doing here is writing the JSON representation of the returned FieldValue object to Realime Database. Apparently, internally, the FieldValue object has a property called "operand" which contains the value to increment by.
I know this post is a couple of years old, but database.ServerValue.increment works with the 11.X firebase-admin Realtime Database like so:
admin.database().ref('counterstest').update({ myusername: database.ServerValue.increment(1) })

How to filter Firestore collection data using function (for location distance filtering)

Would like to know how to filter a Firestore collection of docs using a function where some of the function args are the values of the collection documents.
Suppose had some Firestore collection of documents of the form
{
pointOfInterest: "Some string label"
longitude: -100.123
latitude: 50.456
}
Also have some code that retrieves a user's geocoordinates (in my case, via react-native), so something like
const getCurrentLatLong = () => {
// do some stuff, then...
return { latitude: someNumber, longitude: someOtherNumber }
}
What would ultimately like to be able to do is run something like
let currentLocation = getCurrentLatLong()
let filteredSet = firebase
.firestore()
.collection('MyCollection')
// filtering each individual document
.filter(function (document, currentLocation) {
let docLat = document.latitude
let docLong = document.longitude
return distance(
{latitude: docLat, longitude: docLong},
currentLocation)
< SOME_CONST_DISTANCE
})
So that end up with some filteredSet of all the documents in the collection that have some distance from the currentLocation less than SOME_CONST_DISTANCE.
Some googling led to some potential starting points (https://stackoverflow.com/a/45359952/8236733 and https://firebase.google.com/docs/reference/js/firebase.database.Query#on), but not quite sure how to use what's being shown in the links. Any advice or docs on how to achieve this would be appreciated.
There is no way to pass a function into Cloud Firestore that it then uses to filter the documents that it returns. You either need to pass in static values (e.g. the latitude and longitude you want back), or you will need to read all documents and filter with the function client-side.
What you're trying to do is known as a geoquery: returning documents based on their distance to a known point. Unfortunately that functionality is not built into Cloud Firestore yet, even though it has support for a geographical point data type. It is possible to build it yourself, though you should realize such queries are quite inefficient at the moment.
To learn more about this:
Some developers have ported Firebase's GeoFire library to Firestore. See How to run a geo "nearby" query with firestore?,
I gave a talk about this a while ago, which is available on youtube: https://www.youtube.com/watch?v=mx1mMdHBi5Q
AngularFirebase.com also has a page on Realtime GeoQueries With Firestore
So as answered previously, Firestore doesn't support native geo queries. This is a bit of a shameful plug for some open source stuff I've been working on...
https://github.com/mbramwell1/GeoFire-Android
That lets you do standard Firestore queries, but also adds in the ability to search by location aswell. Give it a look over it may do what you want.

Difference between jsforce bulk api options

I'm using jsforce to access salesforce using the bulk api. It has two ways of updating and deleting records. One is using the normal bulk api which means creating a job and batches:
var job = conn.bulk.createJob("Account", "delete");
var batch = job.createBatch();
var accounts = getAccountsByDate(jsforce.Date.TODAY);
batch.execute(accounts);
batch.on('response', function(rets) {
// do things
});
The other way is to the "query" interface like this:
conn.sobject('Account')
.find({ CreatedDate: jsforce.Date.TODAY })
.destroy(function(err, rets) {
// do things
});
The second way certainly seems easier but I can't get it to update or delete more than 10,000 records at a time, which appears to be a salesforce api limit on batch size. Note that using maxFetch property from jsforce appears to have no effect in this case.
So is it safe to assume that the query style interface only creates a single batch? The jsforce documentation is not clear on this point.
Currently the bulk.load() method in JSforce bulk api generates a job with one batch, so the limit of 10,000 per batch will be applied. It is also true when using find-and-destroy interface, which uses bulk.load() internally.
To avoid this limit you can create a job by bulk.createJob() and create several batches by job.createBatch(), then dispatch the records to delete into these batches so that each records will not exceed the limit.

Get initial collection values from Firebase

In my node app I try to get access to Firebase, which contains a few collections.
var firebase = require('firebase');
firebase.initializeApp({myConfig: "Here"});
var database = firebase.database();
var rootRef = firebase.database().ref()
How exactly do i get all rows of a particular collection or all collections in database? Printing those variables gives strange structured objects.
You should totally be looking into firebase documentation to get this information.
The way you retrieve will depend on what exact behavior you are expecting. And the documentation is excential to understand how firebase behave as a database in wich one of the possible cases.
var rootRef = firebase.database().ref().on('value', function(snapshot) {
console.log(snapshot.val());
});
Snippet above will look into any change on your entire database (since you are not specifying any child like ref().child("users")) and log it as a javascript Object.
Good luck and, again, go to the documentation. :)

Categories

Resources