Firestore Function Trigger wont trigger - javascript

For some reason the onWrite Event is not triggering in Firestore.
Here you see the look of the function in the Firebase Website. Here is the trigger inside of my function ts file:
exports.newCommentCounter = functions.region('europe-west1').database.ref('posts/{PostID}/comments/{CommentID}').onWrite(async(change) => {
The logs are empty like the function never got triggered.
For example adding a Document to posts/postidblabla/comments/commentidblabla wont trigger the function.

If I am not mistaking, this comes from the fact that you are using async in a Node.js 6 Cloud Function.
The following should work:
exports.newCommentCounter = functions.region('europe-west1').database.ref('posts/{PostID}/comments/{CommentID}').onWrite((change, context) => {
=> {})
Also, note that since v 1.0, onWrite() takes two parameters, see https://firebase.google.com/docs/functions/beta-v1-diff#realtime-database.
So, in addition to the change proposed above, please double-check that you have a recent version of the Firebase SDK for Cloud Functions.

Related

Export handler function for AWS Lambda with serverless framework

I have created a handler function which should be accessible via API Gateway (getRecommendation) in a serverless setup
So far I had made this function available via
module.exports.getRecommendation = async (event) => {
// executed code
}
This works just fine
For testing purposes I wanted to make this function accessible also for Jest and defined a different export statement which should work in the same way from my point of view:
module.exports = getRecommendation
async function getRecommendation (event) {
//executed code
}
However, when I run sls offline and try to send data to the endpoint via Postman, I get the error message that
handler 'getRecommendation' in E:\... is not a function
As I would expect the both statements to behave similar I was wondering if you could give me a hint what I'm missing
Thanks

Firebase function .onWrite not working?

Ok, I have looked at similar questions like Firebase function onWrite not being called and thought it was my fault getting the reference, but I have no idea what is happening here with my Firebase functions.
I am just trying to get a function to write to my database when a write has been made to database. I followed the firebase tutorial exactly:
const functions = require('firebase-functions');
// The Firebase Admin SDK to access the Firebase Realtime Database.
//https://firebase.google.com/docs/functions/database-events
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
// const gl = require('getlocation');
exports.helloWorld = functions.https.onRequest((request, response) => {
response.send("Hello from Firebase!");
});
exports.enterLocation = functions.database.ref('/Users/{name}') //brackets is client param
.onWrite(event => {
// Grab the current value of what was written to the Realtime Database.
// const original = event.data.val();
console.log('SKYLAR HERE:', event.params.name);
// You must return a Promise when performing asynchronous tasks inside a Functions such as
return firebase.database().ref('/Users/{name}').set({ location: 'test loc' });
});
The function is being run, yet in my logs I get a pretty unhelpful error that it is getting the {name} param, and data is definitely written to my database, however my SERVER code is not writing:
I get -
ReferenceError: firebase is not defined at
exports.enterLocation.functions.database.ref
Which makes no sense as it is defined. I just want to add an extra child under the user I create, like I do already with "password"
What am I doing wrong?
Two problems here. First, you haven't defined firebase anywhere in your code. I think you meant to use admin instead to use the Admin SDK.
Second, it looks like you're trying to do variable interpolation into a string to build the name of the ref. Your syntax is wrong here.
I imagine you're trying to say this instead in your last line of code:
return admin.database().ref(`/Users/${name}`).set({ location: 'test loc' });
Note the backticks on the string quotes. That JavaScript syntax lets you use ${exp} to insert the contents of some expression in the string.
It turns out you don't even need to use the admin SDK here. Since you're trying to write back to the same location that triggered the function, you can just use the ref that comes from the event object:
return event.data.adminRef.set({ location: 'test loc' });
instead of this:
return firebase.database().ref('/Users/{name}').set({ location: 'test loc' });
use this:
return admin.database().ref('/Users/{name}').set({ location: 'test loc' });

JavaScript function signatures in WebSharper

I am creating an ampify.js binding for the WebSharper. (https://github.com/aph5nt/websharper.amplifyjs). While testing my extension I found one issue with publish / subscribe implementation.
I declared a subscription handler:
let subscribeFn (data:obj) = JS.Alert(data :?> string)
I created a subscription:
Amplify.Amplify.Subscribe("tryPubSub", subscribeFn)
When I want to unsubscribe then I do:
Amplify.Amplify.Unsubscribe("tryPubSub", subscribeFn)
the problem is that, the subscribeFn is was translated into 2 different functions.
If I debug the js code and check what's happening under amplify.js lib, then I get the following:
//this is what has been saved when I created a subscription
subscriptions[ topic ][ i ].callback
(L){return i.subscribeFn(L);}
.
//this is what was passed as a callback for the unsubscribe function
callback
(S){return i.subscribeFn(S);}
There is no difference in the logic, but the args are different and because of that I'm unable to unsubscribe.
WebSharper 3 can't optimize calls to module functions as a function value (which are represented in the quotation as a lambda), so it becomes a new function on every call site.
A solution is to capture the module function as a local function value:
let subscribeFn = fun (o: obj) -> subscribeFn o
(WebSharper 4 beta already has this optimization.)

RxJS Testing Observable sequence without passing scheduler

I have problems attempting to test a piece of code that is similar to the following function.
Basically the question boils down to: is it possible to change the Scheduler for the debounce operator without passing a separate Scheduler to the function call?
The following example should explain the use case a bit more concrete. I am trying to test a piece of code similar to the following. I want to test the chain in the function (using a TestScheduler) without having to pass a scheduler to the debounce() operator.
// Production code
function asyncFunctionToTest(subject) {
subject
.tap((v) => console.log(`Tapping: ${v}`))
.debounce(1000)
.subscribe((v) => {
// Here it would call ReactComponent.setState()
console.log(`onNext: ${v}`)
});
}
The test file would contain the following code to invoke the function and make sure the subject emits the values.
// Testfile
const testScheduler = new Rx.TestScheduler();
const subject = new Rx.Subject();
asyncFunctionToTest(subject);
testScheduler.schedule(200, () => subject.onNext('First'));
testScheduler.schedule(400, () => subject.onNext('Second'))
testScheduler.advanceTo(1000);
The test code above still takes one actual second to do the debounce. The only solution i have found is to pass the TestScheduler into the function and passing it to the debounce(1000, testScheduler) method. This will make the debounce operator use the test scheduler.
My initial idea was to use observeOn or subscribeOn to change the defaultScheduler that is used throughout the operation chain by changing
asyncFunctionToTest(subject);
to be something like asyncFunctionToTest(subject.observeOn(testScheduler)); or asyncFunctionToTest(subject.subscribeOn(testScheduler));
that does not give me the result as i expected, however i presume i might not exactly understand the way the observeOn and subscribeOn operators work. (I guesstimate now that when using these operators it changes the schedulers the whole operation chain is run on, but operators still pick their own schedulers, unless specifically passed?)
The following JSBin contains the runnable example where i passed in the scheduler. http://jsbin.com/kiciwiyowe/1/edit?js,console
No not really, unless you actually patched the RxJS library. I know this was brought up recently as an issue and there may be support for say, being able to change what the DefaultScheduler at some point in the future, but at this time it can't be reliably done.
Is there any reason why you can't include the scheduler? All the operators that accept Schedulers already do so optionally and have sensible defaults so it really costs you nothing given that you production code could simply ignore the parameter.
As a more general aside to why simply adding observeOn or subscribeOn doesn't fix it is that both of those operators really only affect how events are propagated after they have been received by that operator.
For instance you could implement observeOn by doing the following:
Rx.Observable.prototype.observeOn = (scheduler) => {
var source = this;
return Rx.Observable.create((observer) => {
source.subscribe(x =>
{
//Reschedule this for a later propagation
scheduler.schedule(x,
(s, state) => observer.onNext(state));
},
//Errors get forwarded immediately
e => observer.onError(e),
//Delay completion
() => scheduler.schedule(null, () => observer.onCompleted()))
});
};
All the above is doing is rescheduling the incoming events, if operators down stream or upstream have other delays this operator has no effect on them. subscribeOn has a similar behavior except that it reschedules the subscription not the events.

Deps autorun in Meteor JS

Decided to test out Meteor JS today to see if I would be interested in building my next project with it and decided to start out with the Deps library.
To get something up extremely quick to test this feature out, I am using the 500px API to simulate changes. After reading through the docs quickly, I thought I would have a working example of it on my local box.
The function seems to only autorun once which is not how it is suppose to be working based on my initial understanding of this feature in Meteor.
Any advice would be greatly appreciated. Thanks in advance.
if (Meteor.isClient) {
var Api500px = {
dep: new Deps.Dependency,
get: function () {
this.dep.depend();
return Session.get('photos');
},
set: function (res) {
Session.set('photos', res.data.photos);
this.dep.changed();
}
};
Deps.autorun(function () {
Api500px.get();
Meteor.call('fetchPhotos', function (err, res) {
if (!err) Api500px.set(res);
else console.log(err);
});
});
Template.photos.photos = function () {
return Api500px.get();
};
}
if (Meteor.isServer) {
Meteor.methods({
fetchPhotos: function () {
var url = 'https://api.500px.com/v1/photos';
return HTTP.call('GET', url, {
params: {
consumer_key: 'my_consumer_key_here',
feature: 'fresh_today',
image_size: 2,
rpp: 24
}
});
}
});
}
Welcome to Meteor! A couple of things to point out before the actual answer...
Session variables have reactivity built in, so you don't need to use the Deps package to add Deps.Dependency properties when you're using them. This isn't to suggest you shouldn't roll your own reactive objects like this, but if you do so then its get and set functions should return and update a normal javascript property of the object (like value, for example), rather than a Session variable, with the reactivity being provided by the depend and changed methods of the dep property. The alternative would be to just use the Session variables directly and not bother with the Api500px object at all.
It's not clear to me what you're trying to achieve reactively here - apologies if it should be. Are you intending to repeatedly run fetchPhotos in an infinite loop, such that every time a result is returned the function gets called again? If so, it's really not the best way to do things - it would be much better to subscribe to a server publication (using Meteor.subscribe and Meteor.publish), get this publication function to run the API call with whatever the required regularity, and then publish the results to the client. That would dramatically reduce client-server communication with the same net result.
Having said all that, why would it only be running once? The two possible explanations that spring to mind would be that an error is being returned (and thus Api500px.set is never called), or the fact that a Session.set call doesn't actually fire a dependency changed event if the new value is the same as the existing value. However, in the latter case I would still expect your function to run repeatedly as you have your own depend and changed structure surrounding the Session variable, which does not implement that self-limiting logic, so having Api500px.get in the autorun should mean that it reruns when Api500px.set returns even if the Session.set inside it isn't actually doing anything. If it's not the former diagnosis then I'd just log everything in sight and the answer should present itself.

Categories

Resources