When I try to run a function
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
exports.checkPostsRef = functions.https.onRequest((request, response) => {
const postId = 'foo'
admin.database().ref('/posts/' + postId).once('value', snapshot => {
if !snapshot.exists() {
console.log("+++++++++ post does not exist +++++++++") // I want this to print
return
}
});
});
I keep getting an error of Parsing error: Unexpected token snapshot:
Once I comment out if snapshot.exists() { .... } everything works fine.
I'm following this link that says there is an .exists() function, so why am I having this issue?
Good to see how you got it working Lance. Your conclusion on the return being the cause is wrong though, so I'll explain the actual cause below.
The problem is in this code:
if !snapshot.exists() ...
In JavaScript you must have parenthesis around the complete condition of an if statement. So the correct syntax is:
if (!snapshot.exists()) ...
In Swift those outer parenthesis are optional, but in JavaScript (and al other C based languages that I know of), they are required.
turns out it was the return; statement that was causing the problem. I had to use an if-else statement instead.
EDIT As #FrankvanPuffelen pointed out in the comments below the question and his answer, this issue wasn't about the return statement, it was about the way i initially had the !snapshot.exists(). Because it wasn't wrapped in parentheses (!snapshot.exists()) which was causing the problem. So it wasn't the return statement, I know very little Javascript and used the wrong syntax.
if (!snapshot.exists()) {
console.log("+++++++++ post does not exist +++++++++");
} else {
console.log("--------- post exists ---------");
}
FYI I'm a native Swift developer and in Swift you don't need to wrap anything in parentheses. In Swift you can do this:
let ref = Database.database().reference().child("post").child("foo")
ref.observeSingleEvent(of: .value, with: { (snapshot) in
if !snapshot.exists() {
print("+++++++++ post does not exist +++++++++")
return
}
})
Related
i just need someone to tell me what is wrong with my code. This is it.
const getSingletask = async (req, res)=>
{
try{
const task = await Task.findOne({_id:req.params.id})
if(!task){
return res.json({msg:`No such task with and id of ${req.params.id}`})
}
res.json({task})
}catch(error){
res.json({msg:error})
}
}
Basically what the code is doing is that whenever the function excutes, it finds one particular item using its ID. The IF statement is the first error handler. It is meant to return that message if the ID cannot be found but it keeps bringing up an error anytime i test it out. I think my code is correct so can someone tell me what i did wrong?
You seem to be using mongoose. Mongoose saves db objects by way of a wrapper called ObjectId, that accepts exactly 24 hex characters. Because the ID you are inputting into it is not 24 hex characters, mongoose fails to cast it (meaning to use the wrapper), and so, throws an error.
I am having 10 different files and I need to read their content and merge it in one object (in NodeJS). I am successfully doing that with the code below:
const fs = require('fs');
const path = require('path');
const { promisify } = require("util");
const readFileAsync = promisify(fs.readFile);
let filePathArray = ['path/to/file/one', ... , 'path/to/file/ten'];
Promise.all(
filePathArray.map(filePath => {
return readFileAsync(filePath);
})
).then(responses => { //array of 10 reponses
let combinedFileContent = {};
responses.forEach((itemFileContent, index) => {
let tempContent = JSON.parse(itemFileContent);
//merge tempContent into combinedFileContent
}
});
But what I wonder is, how to catch if there is some error while trying to read the files? When reading a single file, this works like:
fs.readFile(singleFilePath, (singleFileErr, singleFileContent) => {
if (singleFileErr) {
//do something on error, while trying to read the file
}
});
So my question here is, how can I access to the error inn the first code snippet, which corresponds to singleFileErr from this second code snippet?
The issue I am facing is: in case some of the files does not exists, I want to check the error and to skip this file, but since I can not detect the error with current implementation, my whole block crashes and I am not able to merge the other 9 files because of this one. I want to use the error check I mentioned in the second snippet.
Check out the Promise.allSettled function, which will run every Promise passed to it, and will tell you at the end which ones succeeded and which ones failed.
Maybe try something like this:
in the map() callback, return a promise that resolves to null if the file is not found.
Introduce a middle stage in the promise chain filtering out null responses.
This would look something like this:
Promise.all(
filePathArray.map(filePath => {
return readFileAsync(filePath).catch(function(error){
if(isErrorFileDoesNotExist(error)) return null
throw error;
})
});
).then(responses => {
return responses.filter(response => response != null)
})
.then(filteredResponses => {
// .. do something
});
Would that work for you? Note this presupposes you are actually able to discriminate between missing file errors from other errors the promise returned by readFileAsync() may reject - presumably via the isErrorFileDoesNotExist() function in this snippet.
I'm building a cloud function that will use the Stripe API to process payments. This is within a firebase project. When I run firebase deploy I get the error "Object is possible 'undefined'" const existingSource = customer.sources.data.filter( (s) => s.id === source).pop();
I'm not sure how to resolve this.
Here is my xxx.ts where getorCreateCustomer exists
/** Read the stripe customer ID from firestore, or create a new one if missing */
export const getOrCreateCustomer = async(uid: string) => {
const user = await getUser(uid);
const customerId = user && user.stripeCustomerId;
//if missing customerId, create it
if (!customerId) {
return createCustomer(uid);
}
else {
return stripe.customers.retrieve(customerId);
}
}
Based on the definitions and contents of your functions, TypeScript is unable to infer the return type of getOrCreateCustomer. It is making the assumption that it could return undefined, and its strict mode is calling you out on the fact that you could be referencing a property on an undefined object, which would result in an error at runtime.
What you need to do is declare the return type to be something that can't possibly be undefined, and make sure the code in the body of the function is correct on that guarantee (otherwise you'll get a new error).
If you can't do that (but you really should do that), you might want to instead disable strict mode in your tsconfig.json file, since that is what's enforcing this level of correctness in your code.
I suggest the first option, even if you have to write more lines of code, as it's a better use of TypeScript's typing system.
What #Doug mentioned, but also you could write your logic to make sure that every part of customer.sources.data is not undefined...
ie:
const { sources } = customer
if (sources) {
const { data } = sources
if (data) {
// then filter / etc etc ...
}
}
7 months later, I figured out the best solution.
I simply wrapped the the contents of the firebase callable function in the following if/else statement. It's a bit redundant but it works.
if (!context.auth) {
// Throwing an HttpsError so that the client gets the error details.
throw new functions.https.HttpsError('failed-precondition', 'The function must be called ' +
'while authenticated.');
}
else{ ...copy function code here }
If you don't care about the authentication piece you can simply define the type of context as any.
(data, context:any)
Open tsconfig.json and add "strictNullChecks": false to angularCompilerOptions object. It worked for me.
{
...
"angularCompilerOptions": {
"strictNullChecks": false,
...
}
}
I'm dipping my toe into Mendix Typescript SDK and followed the instructions on https://docs.mendix.com/apidocs-mxsdk/mxsdk/setting-up-your-development-environment.
I then followed https://docs.mendix.com/apidocs-mxsdk/mxsdk/creating-your-first-script to create a script to try it out.
However, I'm getting the following error to the code script.ts suggested on this page:
error TS2554: Expected 1-2 arguments, but got 0.
30 return dm.load();
~~~~~~~~~
node_modules/mendixmodelsdk/dist/gen/domainmodels.d.ts:583:14
583 load(callback: (element: DomainModel) => void, forceRefresh?: boolean): void;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
An argument for 'callback' was not provided.
Found 1 error.
return dm.load();
I'm not NodeJS savvy - but I can tell the parameter passed in to load() is incorrect - just doesn't exists although load() is defined to take a parameter. But then, why the error to a script on the suggested setup? I'll attack this issue. But need help on where to start.
This "feels" like a version difference/setup error. But I've seen no errors anywhere else while I was setting it up.
What am i missing?
I don't have experience in making that particular example script work; it might as well be out of date. In my own script, I'm loading the data model with the loadAsPromise function, as indicated in the script in the article Generate Code from the Model.
async function serializeToJs() {
const workingCopy = await project.createWorkingCopy();
const domainModelInterface = workingCopy.model().allDomainModels().filter(dm => dm.containerAsModule.name === moduleName)[0];
try {
const domainModel = await loadAsPromise(domainModelInterface);
console.log(JavaScriptSerializer.serializeToJs(domainModel)); //print out the generated JavaScript
console.log("success!")
} catch (error) {
console.log(`error: ${error}`);
}
}
I'm trying to update one value after a write completes (in a Cloud Function) but it just wont work (I'm sure this is a stupidly simple problem). Code below:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const firebase = require('firebase');
admin.initializeApp(functions.config().firebase);
exports.createMessage = functions.https.onRequest((request, response) => {
const json = JSON.parse(request.query.json); // == "{'start':0, 'end':0}"
json.start = firebase.database.ServerValue.TIMESTAMP;
admin.database().ref('/messages/').push(json).then(snapshot => {
//Here is the problem. Whatever I try here it won't work to retrieve the value.
//So, how to I get the "start" value, which has been written to the DB (TIMESTAMP value)?
var startValue = snapshot.ref.child('start').val();
snapshot.ref.update({ end: (startValue + 85800000) }).then(snapshot2=>{
response.redirect(303, snapshot.ref);
});
});
});
Is the problem that I'm using admin.database()?
This code:
var startValue = snapshot.ref.child('start').val();
doesn't actually retrieve any values. Take a look at the docs for DataSnapshot. Reach into that snapshot directly with child() - you don't need the ref. Maybe this is what you meant?
var startValue = snapshot.child('start').val();
I'm not sure if there's a bug in Firebase or if I'm using it wrong, but if I try to call any method on the snapshot-reference I will only get an error saying: TypeError: snapshot.xxx is not a function where xxx is the function name i try to use (for example: child(...), forEach(...), etc).
However, the following seems to fix the issue with the snapshot:
admin.database().ref('/messages/').push(json).once('value').then(snapshot => {
instead of:
admin.database().ref('/messages/').push(json).then(snapshot => {
My uneducated guess is that the then-promise, for the push-function returns some faulty snapshot since the only thing that seems to work is snapshot.key.
Also, if I'm not mistaken, doesn't my solution make two reads now, instead of one? Since push will write and then (supposedly) read and return the written value and then I read it once more with once(value).
Does anyone has any further insights into this problem?