Is it possbie to make an if condition based on Firebase data - javascript

I need to make some if statements for advanced filter search and also some if conditions to make a table filterable. Is there any way to make if statements based on Firebase. I need to make the output from Firebase true and false to replace with archived and display it in a dynamic table.
Thank you in advance.
e.g.
var usersRef = firebase.database().ref("users");
var query = usersRef.orderByChild("disabled").equalTo(true);
query.on("value", function(snapshot) {
snapshot.forEach(function(user) {
if (user.disabled != true) {
$('#ArchiveLabel').text("Archived");
} else {
$('#ArchiveLabel').text("");
}
}); });

You're looking for something along these lines:
var usersRef = firebase.database().ref("users");
var query = usersRef.orderByChild("something").equalTo(true);
query.on("value", function(snapshot) {
snapshot.forEach(function(user) {
console.log(user.key, user.val());
});
});
I highly recommend that you spend some time in the Firebase documentation, for example its section on ordering and filtering data. You also might benefit from taking the Firebase codelab for web developers.

Related

Execute SPARQL Query with vue.js

I want to make a website by implementing the use of sparql in vue js. The scenario I want is to create a special place to write Sparql Query and then execute it with vue.js. Is all that possible? if possible how should i start it? if not possible, is there any other alternative than using vue.js? Please help.
I am not a JS pro by any means. Anyway, for a similar problem, I used axios for the HTTP request.
This worked fine for my use case. Anyway, you will find a precise description of the JSON format at https
var params = new URLSearchParams();
// queryArtistsByNameTpl contains the actual SPARQL query,
// with $artistName as a placeholder
let similarGroupsQuery = queryArtistsByNameTpl.replace("$artistName", this.artistName);
params.append('query', similarGroupsQuery);
let getArtistsHandler = sparqlResponseHandler(this, 'artistList');
axios.post(sparqlEndPoint, params).then(getArtistsHandler);
function sparqlResponseHandler(currentObj, currList) {
return function(response) {
const rows = response.data.results.bindings;
currentObj[currList] = [];
if (rows.length > 0) {
rows.forEach(function(item, index) {
var record = {};
for (var prop in item) {
if (item.hasOwnProperty(prop)) {
record[prop] = item[prop].value;
}
}
currentObj[currList].push(record);
})
} else {
console.log("no data from SPARQL end point");
}
}
}
The JSON resturned by SPARQl endpoints is specified in https://www.w3.org/TR/sparql11-results-json/ , which is rather short and very understandable.
The code can certainly be improved by someone more knowledgeable then me, but it was fine for the tech demo we used it for.

Firebase Functions: orderBy function not working

The following code works in the emulator but returns an empty array in firebase when includeVideos or includeAudios is false:
let query = db.collection("content");
if (includeVideos && !includeAudios) {
query = query.where("type", '==', "video").orderBy("type");
}
if (includeAudios && !includeVideos) {
query = query.where("type", '==', "audio").orderBy("type");
}
if (!includeVideos && !includeAudios) {
return {empty json....}
}
if (matchingPersonID != undefined) {
query = query.where("attributionID", '==', matchingPersonID).orderBy("attributionID");
}
//either categories OR matchingSeriesID is always undefined/empty
if (matchingSeriesID != undefined) {
query = query.where("seriesIDs", 'array-contains', matchingSeriesID).orderBy("seriesIDs");
}
if (matchingCategories.length != 0) {
// 'OR' LOGIC
query = query.where("categories", 'array-contains-any', matchingCategories).orderBy("categories");
}
if (lastDocumentID != undefined) {
await db.collection("content").doc(lastDocumentID).get().then((snapshot) => {
query = query.startAfter(snapshot);
log(`starting after document ${snapshot}`)
})
}
//the code works when this line is removed, but the query needs to be sorted by time in order for pagination to work
query = query.orderBy("upload_date", "desc");
return query.limit(getNext).get()...
I get no error messages in the google cloud logs, and so I have no easy way of creating an index, if that's what I need to do.
In firestore, the fields upload_date, attributionID, type, seriesIDs, and categories are all on the same level in the document.
Any help would be much appreciated!!
As you comment, it seems that an index for that field is missing.
This documentation mentions two ways to handle these indexes:
By using the CLI. You can bring your indexes to a local file in a JSON format. For this, run firebase firestore:indexes inside your firebase project folder, you'll get a formatted JSON output for you to copy, add a new one and then deploy them with firebase deploy --only firestore:indexes.
Indeed, you can use the URL generated by Firebase when it catches the error of using an index that does not exist, but you can also do it by hand from the Firebase console of the application:

How to make separate login for Users and Freelancer based on Roles that is in my real time database Firebase

Hello I am working a web application with Firebase Realtime Database and Authentication with nodejs or javascript.
This is my real time database and I want to make a login form which if the User = User he will go to User Index and if the User = Freelancer he will go to Freelancer Index.
And this is the line of code that I was tweaking or trying but It doesn't go in my way.
<script>
firebase.auth().onAuthStateChanged(function(user)
{
if(user)
{
var userID = firebase.auth().currentUser.uid;
firebase.database().ref('Users/' + userID).once('value').then(function(snapshot)
{
if (snapshot.val())
{
window.location.href = "index.html";
}
else
{
window.location.href = "okay.html";
}
});
}
});
</script>
Hoping I can get feedbacks or answers here. I am almost trying it for 2days already that's why I seek help here.
Comments and answers are highly appreciated thank you!
With your current data structure you will need to check in two places to determine what role a user has. While this technically possible, it is less efficient and more complex in code.
I recommend instead to store a single top-level node (say UserRoles) where you simply keep the role for each UID:
"UserRoles": {
"uidOfUser1": "Freelancer",
"uidOfUser2": "User"
}
With that in place, you can load it in your onAuthStateChanged callback with:
const ref = firebase.database.ref("UserRoles");
ref.child(user.uid).once("value").then((snapshot) => {
if (snapshot.val() === "Freelancer") {
window.location.href = "okay.html";
}
else if (snapshot.val() === "User") {
window.location.href = "index.html";
}
else {
alert("Can't determine role for user: "+user.uid)
}
});

How to get database value not related to the event in Cloud Functions for Firebase?

I have a firebase database and I am currently trying to use cloud functions to perform an operation when a value in my database changes. So far, it successfully triggers code to run when the value in my database changes. However, when the database value changes, I now need to check another value to determine it's status, and then perform an action after that. The problem is that I have ~0 experience with JS and I have no way of debugging my code other than deploying, changing the value in my database, and looking at the console log.
Is there any way to look up another value in the database and read it? How about look up a value and then set a value for it? Here is the code:
exports.determineCompletion =
functions.database.ref('/Jobs/{pushId}/client_job_complete')
.onWrite(event => {
const status = event.data.val();
const other = functions.database.ref('/Jobs/' + event.params.pushId + '/other_job_complete');
console.log('Status', status, other);
if(status == true && **other.getValueSomehow** == true) {
return **setAnotherValue**;
}
});
This code partially works, it successfully gets the value associated with client_job_complete and stores it in status. But how do I get the other value?
Additionally, if anyone has any JS or firebase documentation that they think would help me, please share! I have read a bunch on firebase here : https://firebase.google.com/docs/functions/database-events but it only talks about events and is very brief
Thank you for your help!
When writing a database trigger function, the event contains two properties that are references to the location of the data that changed:
event.data.ref
event.data.adminRef
ref is limited to the permissions of the user who triggered the function. adminRef has full access to the database.
Each of those Reference objects has a root property which gives you a reference to the root of your database. You can use that reference to build a path to a reference in another part of your database, and read it with the once() method.
You can also use the Firebase admin SDK.
There are lots of code samples that you should probably look at as well.
I'm maybe a bit late, but I hope my solution can help some people:
exports.processJob = functions.database.ref('/Jobs/{pushId}/client_job_complete').onWrite(event => {
const status = event.data.val();
return admin.database().ref('Jobs/' + event.params.pushId + '/other_job_complete').once('value').then((snap) => {
const other = snap.val();
console.log('Status', status, other);
/** do something with your data here, for example increase its value by 5 */
other = (other + 5);
/** when finished with processing your data, return the value to the {{ admin.database().ref(); }} request */
return snap.ref.set(other).catch((error) => {
return console.error(error);
});
});
});
But take notice of your firebase database rules.
If no user should have access to write Jobs/pushId/other_job_complete, except Your cloud function admin, You need to initialize Your cloud function admin with a recognizable, unique uid.
For example:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const adminCredentials = require('path/to/admin/credentials.json');
admin.initializeApp({
credential: admin.credential.cert(adminCredentials),
databaseURL: "https://your-database-url-com",
databaseAuthVariableOverride: {
uid: 'super-special-unique-firebase-admin-uid'
}
});
Then Your firebase database rule should look something like this:
"client_job_complete": {
".read": "auth !== null",
".write": "auth.uid === 'super-special-unique-firebase-admin-uid'"
}
Hope it helps!
You have to wait on the promise from a once() on the new ref, something like:
exports.processJob = functions.database.ref('/Jobs/{pushId}/client_job_complete')
.onWrite(event => {
const status = event.data.val();
const ref = event.data.adminRef.root.child('Jobs/'+event.params.pushId+'/other_job_complete');
ref.once('value').then(function(snap){
const other = snap.val();
console.log('Status', status, other);
if(status && other) {
return other;
}
});
});
Edit to fix the error that #Doug Stevenson noticed (I did say "something like")

Will Mongo handle my service?

I've been using MongoDB with node.js and mongoose library. I decided to start using MongoDB because I found everywhere that it is the best solution for node.js applications.
Although the response times of my API are good, I'm unsure that MongoDB will handle it when scaling it.
I've noticed that most of my queries aren't enough to get all the data I need, so I rely on creating several queries and using some javascript map/reduce functions (that is what I'm afraid of).
Look at this example:
User
.find({
idol : true
})
.sort({
'metas.followers' : -1
})
.select('-password -__v -posts -email')
.skip(offset)
.limit(30)
.exec(function(err, retData)
{
promisedIdols = retData.map(function(idol)
{
return idol.withStatistics(Post, Follow, req.user);
});
idols = [];
if(promisedIdols.length == 0)
{
callback();
}
for(var i=0; i<promisedIdols.length; i++)
{
promisedIdols[i].delegate(function(result)
{
idols.push(result);
if(idols.length == promisedIdols.length)
{
callback();
}
});
}
});
I've used a map to gather an array of promises that will be resolved after running the following code:
var obj = this.toObject();
var deferred = new Promise();
Post
.find({ idol : obj._id })
.lean()
.exec(function(err, posts)
{
var postViews = 0;
var postLikes = 0;
var postShares = 0;
posts.reduce(function(prev, next)
{
postViews += next.views.length;
postLikes += next.likes.length;
postShares += next.shares.length;
}, 0);
obj.metas.postViews = postViews;
obj.metas.postLikes = postLikes;
obj.metas.postShares = postShares;
obj.metas.postCount = posts.length;
Subscription
.count({ idol : obj._id }, function(err, count)
{
obj.metas.subscribers = count;
deferred.deliver(obj);
});
});
that uses a reduce function.
I can't see this code working well on big scale. Maybe should I restructure my database? Maybe should I change my database system? Maybe I'm using MongoDB wrongly?
Experts?
Thanks.
Mongo can handle a lot, if you setup a good data model. There are a few things to keep in mind when you want to scale.
Try to avoid normalizing the data much and split it into different collections.
Data duplication is (sometimes, when used wisely) your friend, it will help you make simpler queries, populate right away. Yeah, that may mean that when you're updating data, you'll have to update in two places, but Mongo is ok with a lot of writes if you do it asynchronously (promises or not).
To your specific query, I don't see the full data model, but maybe you can use aggregation framework. That pipeline is native (C++, as opossed to mapReduce JavaScript) and will work really really fast.
Something like:
db.post.aggregate(
// First $match to reduce the dataset
{
$match: {idol : obj._id}
},
// then group and aggregate your data
{
$group: {
_id: '$idol', // group by that idol thing
postViews: {$sum: '$postViews'},
postLikes: {$sum: '$postLikes'}
},
},
// Then use project to arrange the result the way you like it
{
$project: {
_id: false, //or true if you need it
metas: {
postViews: '$postViews'
},
likeCountOfPosts: '$postLikes', // that's how you'd rename
whatIsIt: {$literal: 'a great post'}
}
}
);
You can also do a lot of conditional, groupings, sortings, winding and unwinding, mixing and shuffling the pipeline.
It's much much faster then Mongo mapReduce.

Categories