How to turn non-idiomatc nodejs callback into thunk? - firebase

I'm using the Firebase node module and trying to convert it's callbacks to thunks to be able to use them in Koa.
This is the original event listener callback as per the Firebase documentation:
projects.on('value', function (snapshot) {
console.log('The read succeeded: ' + snapshot.val());
}, function (errorObject) {
console.log('The read failed: ' + errorObject.code);
});
And this is the where I want to add it in my Koa project:
function *list() {
// Get the data here and set it to the projects var
this.body = yield render('list', { projects: projects });
}
Anyone know how to to do it? Have tried thunkify, thunker and thu without success...

I don't think you can use thunkify etc because they are trying to convert a standard node function to a thunk. The firebase api doesn't follow the standard node.js callback signature of
fn(param1, parm2,.., function(err, result){});
which thunkify is expecting.
I think this would do it
var findProjectsByValue = function(value){
return function(callback){
projects.on(value, function(result){
callback(null, result);
}, function(err){
callback(err);
})
}
};
then you would consume it
var projects = yield findProjectsByValue('value');
Or you could just do rest api calls, which I assume is what you want. The firebase api seems to be more for evented scenarios, socketio etc

Related

How to Use Firebase with Nativescript-Vue?

I've been trying to implement just a simple Firebase fetch since November. At this point, I wish I'd just created a new Rails api; it would have been faster.
But everyone insists Firebase is Oh So Simple.
In app.js,
import firebase from 'nativescript-plugin-firebase';
That part seems OK.
Instructions are all over the place after that.
The plugin's ReadMe suggests an initialization:
firebase.init({
// Optionally pass in properties for database, authentication and cloud messaging,
// see their respective docs.
}).then(
function () {
console.log("firebase.init done");
},
function (error) {
console.log("firebase.init error: " + error);
}
);
Several others have insisted that the init code is unnecessary. It does run without errors, but the code he gives after that produces nothing. Also,
const db = firebase.firestore;
const UserStatusCollection = db.collection("UserStatus");
UserStatusCollection.get();
produce an empty object {}.
Here's my Firebase collection:
If I wrap the firebase call in async/await (and no one is showing it as this complicated),
async function getFireStoreData() {
try {
let result = await this.UserStatusCollection.get();
console.log(result);
return result;
}
catch (error) {
console.error(
"UserStatusCollection.get()" + error
);
}
}
And call that
let temp2 = getFireStoreData();
console.log("temp2:" + temp2);
All I ever get is an object promise.
As I said, I wish I had just built up a new Rails API and had a far simpler life since November.
Your getFireStoreData method is asynchronous and you're not awaiting it. That is probably the reason why you're getting a promise back. Try to await getFireStoreData(). See if that works.
Since it's also a promise, you can try to use .then.
getFireStoreData().then(data => {
console.log(data);
})

What is the difference between publish / subscribe and method ? where/when we use method and publish / subscribe?

Today I try to work on meteor and getting an issue to get data from the server page..
I try to search it on google and meteor side but there is two way to get data publish / subscribe and Method
Have a below code, I didn't know how to write it on meteor server-side and get that data in client-side
function (x)
{
var y =2
var z = y*x
return z;
}
Now I want to call this method in client side
With publish/subscribe you keep track on datas collected.
https://docs.meteor.com/api/pubsub.html
According to the documentation:
Methods are remote functions that Meteor clients can invoke with
Meteor.call.
So, to answer the last question: to call your function from client side, you have to use "Meteor.call('yourMethodName', optionalCallBacks);"
EDIT:
Ok, as suggested in the comments, here an example, with your function.
In the server side, lets say on a file called "methods.js" or somethings:
import { Meteor } from 'meteor/meteor';
Meteor.methods({
myMethod(x) {
const y = 2;
const z = y * x;
return z;
}
});
then in client side, you could call this mehod, like:
Meteor.call('myMethod', x, (error, result) => {
// OPTIONAL CALLBACK RESULT
console.log(error, result);
});
Arguments here, are respectivelly, name of the method, variable named x, callback.
What is the difference between publish / subscribe and method ? where/when we use method and publish / subscribe?
So if you want a logic you don't need pub/sub.
Methods are for logic pub/sub for data handling.
Important note:
If you need to work with data from meteor's collection on the method you need to take into account this if method is executed on the server side it has access to all data (collections).
If the method is executed on the client side it has access only to published data.
On the other hand, according to your example, you don't need any data, so I'll skip it.
I strongly suggest using validated methods:
https://github.com/meteor/validated-method
Now let's go to examples
Imagine you have a method
export const calculate = new ValidatedMethod({
name: 'logic.calculate', // methods are usually named like this
validate: new SimpleSchema({ // use SimpleSchema to autovalidate parameters
x: {
type: Number
}
}).validator(),
run({ x }) {
const y = 2;
return y*x;
}
});
Things to note:
1. The file should be imported on the server somewhere.
2. You need to use validation
Now call it on the client
Meteor.call('logic.calculate', { x }, (error, result) => {
if (error) {
do something
}
console.log(result);
});
Also, you can import the method directly and call it like this:
import { calculate } from '../../api/logic/methods';// use real method path here
calculate.call({ x }, (error, result) => {
if (error) {
do something
}
console.log(result);
});
Note that for validated methods argument is an object
In meteor, we can create a meteor method and can pass data to client side by Meteor.call('methodName', 'param') . But in case of async operation we need to use future. Take a look on below example :
Future = Npm.require('fibers/future');
Meteor.methods({
foo: function() {
const future = new Future();
someAsyncCall(foo, function bar(error, result) {
if (error) future.throw(error);
future.return(result);
});
// Execution is paused until callback arrives
const ret = future.wait(); // Wait on future not Future
return ret;
}
});

What is a method of using Firebase Cloud Functions in Flutter.

I have been searching all over on how to implement firebase functions with a flutter application. It does not seem like there is an SDK available (yet). I've also tried adding the gradle dependency implementation 'com.google.firebase:firebase-functions:15.0.0' to my app/build.gradle but this causes build errors.
Has anyone done an implementation that works? I am unable to find any documentation on how to handle credentials and the transport of data in order to build my own firebase functions call.
I have created a rough outline of how I am thinking this is intended to work, but may be way off base.
Future<dynamic> updateProfile(String uid, AccountMasterViewModel avm) async {
Uri uri = Uri.parse(finalizeProfileFunctionURL);
var httpClient = new HttpClient();
String _result = '';
try {
return await httpClient
.postUrl(uri)
.then((HttpClientRequest request) {
return request.close();
// authentication??
// Fields and data??
})
.then((HttpClientResponse response) async {
print(response.transform(new Utf8Codec().decoder).join());
if (response.statusCode == HttpStatus.OK) {
String json = await response.transform(new Utf8Codec().decoder).join();
_result = jsonDecode(json);
// Do some work
return json;
}
else {
return ':\nHttp status ${response.statusCode}';
}
});
}
catch (exception) {
return 'Failed ' + exception.toString();
}
}
I'd like to be able to send an object, like
{
accountID: src.accountID,
accountName: src.name,
accountImg: src.image
}
and then handle the response. But as I said, I can't find any working examples or tutorials on how to do this. It's fairly simple to do this client size and talk directly to the database, however, there are validations and data components that need to be hidden from the client, so cloud functions is the way I would like to do this.
Yes, there is a cloud_function package available here: https://pub.dartlang.org/packages/cloud_function.
so as to make a call to the function you can just call
CloudFunctions.instance.call(
functionName: 'yourCloudFunction',
parameters: <String, dynamic>{
'param1': 'this is just a test',
'param2': 'hi there',
},
);
An updated answer to calling Firebase's Cloud Functions in Flutter would be
var callable = CloudFunctions.instance.getHttpsCallable(functionName: 'functionName'); // replace 'functionName' with the name of your function
dynamic response = callable.call(<String, dynamic>{
'param1': param1 //replace param1 with the name of the parameter in the Cloud Function and the value you want to insert
}).catchError((onError) {
//Handle your error here if the function failed
});
This is a good tutorial on cloud functions in flutter which helped me:
https://rominirani.com/tutorial-flutter-app-powered-by-google-cloud-functions-3eab0df5f957
Cloud functions can be triggered by data change triggers in the realtime database, Firestore, or Datastore, as well as authentication triggers.
You could just persist
{
accountID: src.accountID,
accountName: src.name,
accountImg: src.image
}
to the database and register a trigger that runs a Cloud Function when data at a specific path is inserted, updated, or deleted.
https://firebase.google.com/docs/functions/firestore-events

From which file do I send a push notification in strongloop?

I am trying to set up push notifications with strongloop. I don't understand which file the code below lives in. The docs don't say, which is confusing for newbies.
I understand that I have to add a push component to loopback restful api application, which I have done. But how do I reference the push component from my restful api app? Where's the 'glue'?
http://docs.strongloop.com/display/public/LB/Push+notifications
var badge = 1;
app.post('/notify/:id', function (req, res, next) {
var note = new Notification({
expirationInterval: 3600, // Expires 1 hour from now.
badge: badge++,
sound: 'ping.aiff',
alert: '\uD83D\uDCE7 \u2709 ' + 'Hello',
messageFrom: 'Ray'
});
PushModel.notifyById(req.params.id, note, function(err) {
if (err) {
// let the default error handling middleware
// report the error in an appropriate way
return next(err);
}
console.log('pushing notification to %j', req.params.id);
res.send(200, 'OK');
});
});
This should live in the app.js file as seen in the example here:
https://github.com/strongloop/loopback-component-push/blob/master/example/server/app.js#L137-L145

Can I publish only Collections object in meteor?

On the introducing article of DDP, I read that anything can be published, but I've read somewhere ( for example in this Stackoverflow comment Publish arbitrary data and automatically update HTML ) that only Collections can be published.
So where is the truth? If we can publish other things than Collections, I would liek to see an example as I can't find one so far.
From the docs: http://docs.meteor.com/#meteor_publish
Publish functions can return a Collection.Cursor, in which case Meteor will publish that cursor's documents. You can also return an array of Collection.Cursors, in which case Meteor will publish all of the cursors.
So at the moment you can only return a Collection via a cursor (result of a Collection.find()).
To return other data you need to hack into the sockjs stream (the socket library meteor uses to communicate to the server). Be aware this does not guarantee compatibility with future versions of meteor. Sockjs is the library used for meteor to communicate between the server (the wire)
from Publish arbitrary data and automatically update HTML*
client side js
sc = new Meteor._Stream('/sockjs');
sc.on('message', function(payload) {
var msg = JSON.parse(payload);
Session.set('a_random_message', JSON.stringify(msg.data));
});
Template.hello.greeting = function () {
return Session.get('a_random_message');
};
server side js
ss = new Meteor._StreamServer();
ss.register(function (socket) {
var data = {socket: socket.id, connected: new Date()}
var msg = {msg: 'data', data: data};
// Send message to all sockets (which will be set in the Session a_random_message of the client
_.each(ss.all_sockets(), function(socket) {
socket.send(JSON.stringify(msg));
});
});
You can also look at Meteor Streams too. See below.
assume you have added meteor streams via atmosphere - mrt add streams
sc = new Meteor.Stream('hello');
if(Meteor.isServer) {
Meteor.setInterval(function() {
sc.emit('a_random_message', 'Random Message: ' + Random.id());
}, 2000);
Meteor.permissions.read(function() { return true });
}
if(Meteor.isClient) {
sc.on('a_random_message', function(message) {
Session.set('a_random_message', message);
});
Template.hello.greeting = function () {
return Session.get('a_random_message');
};
}

Resources