Parse Cloud Code runs on client side but not on server side - parse-platform

I wrote this large parse code for Parse Cloud Code that queries a row based on it's objectId. I wrote this all on my client-side and tested it with my localized html code. Everything works great! But, once I push it to the server and attempt to run I get Error 141 : "An error has occured"
Clearly, this is massively unhelpful. So, I broke the code down to the most basic call I can make, shown below:
function getCardPacks(request, response)
{
var myTable = Parse.Object.extend("myTable");
var query = new Parse.Query(myTable);
query.get(request.params.tabId,
{
success:function(results)
{
response.success();
},
error:function(error)
{
response.error(error);
}
},function(error)
{
console.log(error);
});
I still get the 141. I verified that the params I send this function are not null, but maybe they are getting undefined before they reach the function? I really have no idea what is wrong here.
Has this happened to anyone else? Or, is there a way I can get debug logs from the server end so I could determine if a val is null or find out where the script stops?

Well you can check the logs on Parse.com on your app. I'm confused what you are using cloud code for. If you are just querying a table, then you should be able to do that using the Parse javascript sdk. You can see how to set that up here. https://www.parse.com/apps/quickstart?app_id=syncup-staging#parse_data/web/existing

Related

How can I get Google Auth working with Laravel?

I'd like to know if there's an easy fix for this error that I'm getting while trying to add support for Google sign-in to my website, since I can only reproduce it while on a Laravel-based environment. Vanilla PHP applications do run just fine.
This is my relevant code:
if ($request->has('googleToken')) {
$client = new Google_Client(['client_id' => env('GOOGLE_PLATFORM_CLIENT_ID') ]);
$payload = $client->verifyIdToken($credentials['googleToken']);
if (!$payload) {
return response([ 'error' => 'Invalid token, please try using form-based authentication.' ], Response::HTTP_FAILED_DEPENDENCY);
}
$user['googleToken'] = $credentials['googleToken'];
}
I know I'm doing too relaxed validations, but please just focus on the fact that I'm just testing and I plan to change this code in the near future.
The code above, receives its data through an Axios PUT request from the frontend with the payload looking like this:
{
googleToken: "eyJhbGciOiJSUzI1NiIsImtpZCI6IjE5ZmUyYTdiNjc5NTIzOTYwNmNhMGE3NTA3OTRhN2JkOWZkOTU5NjEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJhY2NvdW50cy5nb29nbGUuY29tIiwiYXpwIjoiNTkyODkzNjE3ODYzLXRscDdvaDByaTk2dTZxZGxrOXYwbHAyanQyNDlkdDNsLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwiYXVkIjoiNTkyODkzNjE3ODYzLXRscDdvaDByaTk2dTZxZGxrOXYwbHAyanQyNDlkdDNsLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwic3ViIjoiMTE1NTg0MDg0NTE2OTMxOTQzODU..."
mailAddress: "user#mail.com"
}
The problem is that the payload would simply return false. I decided to try to investigate the issue, so I went to the definition of verifyIdToken contained within Google_Client and, from there, jumped over to the function that finally returns to its parent, which is verifyIdToken from the class Verify.
Inside of that class, there's a pretty loose try/catch block in which I decided to try adding a generic exception case so that I could quickly print the error message for debugging. I did, and this is the output I got:
OpenSSL unable to verify data: error:0909006C:PEM routines:get_name:no start line
This is what's failing internally, and from this point on, I don't really have an idea about how to proceed since the error feels very cryptic, or at least it's not in my field of knowledge.
The OpenSSL error you quoted indicates that your client was not able to read any/further PEM-encoded data. Refer to https://www.openssl.org/docs/man1.1.1/man3/PEM_read.html.
OpenSSL unable to verify data: error:0909006C:PEM routines:get_name:no start line
Here,
'PEM routines' represents the library within OpenSSL
'get_name' is the function
'no start line' is the reason
Is you client able to access the necessary certificates/keys?

How do I make Apollo Client tell me where in my code the error happened?

I'm learning React/Apollo and when I introduce bugs I get the typical red exceptions in my Chrome console. However, with Apollo, it doesn't tell me where in my code the error began as it does in React or other frameworks. When working with hooks that fire off queries in multiple components it makes it exceedingly slow to find the source of the issue.
Do you use any tricks to debug your Apollo code or can you improve the error feedback in some way?
Here's what I see:
ApolloError.ts:46 Uncaught (in promise) Error: GraphQL error: User is not authenticated
at new ApolloError (ApolloError.ts:46)
at QueryManager.ts:1241
at Object.next (Observable.js:322)
at notifySubscription (Observable.js:135)
at onNotify (Observable.js:179)
at SubscriptionObserver.next (Observable.js:235)
at observables.ts:12
at Set.forEach (<anonymous>)
at Object.next (observables.ts:12)
at notifySubscription (Observable.js:135)
at onNotify (Observable.js:179)
at SubscriptionObserver.next (Observable.js:235)
at httpLink.ts:142
First, I'd like to address the specific error you're seeing in your question.
User is not authenticated would indicate to me that this is not an issue on the client side (most likely) and you are trying to make a query that requires authentication. The reason you aren't authenticated might have something to do with the client, but it's going to be pretty much impossible for any frontend framework to tell you where that issue is.
As far as general techniques for debugging apollo-client issues go? Well, when using #apollo/react-hooks, you will get feedback about errors from the value's the hook returns directly. For example, with the useQuery hook:
const Employee = () => {
const { data, loading, error } = useQuery(LOAD_EMPLOYEE_DATA_QUERY);
if (error) {
console.error(error);
throw error;
}
// ...
}
If something went wrong, either on the client or the server, you would get feedback about that in the error object. This makes it fairly straightforward to debug.
Sometimes, things aren't so simple though. The next place I usually look to when there are apollo-client issues are the Apollo dev tools. It will show you what queries were made and their results.
Finally, if that doesn't work, then I would start digging through the network tab for XHR requests to /(insert your graphql endpoint here). If there is red, then you should look at the console output from your server.
Hope that this helps!
Those errors are actually when you run ApolloClient.query() and have uncaught errors.
This is what I did to handle it. (But ideally you would use useQuery) instead
const apiClient = new ApolloClient({
... // Your ApolloClient options
});
const originalQuery = apiClient.query;
apiClient.query = (...args) => {
// Get the original stack trace instead to figure out where our uncaught error is
const stackTrace = new Error().stack;
return originalQuery(...args).catch(e => {
e.stack = stackTrace;
throw e;
});
};
This way when I get a stack trace it'll actually be where I used this particular Query()

Receiving and responding to Twilio SMS using parse cloud module

I have a cloud code function that I use to send a text message to a number that is determined in my app (iOS).
The message sends fine, but I want the person who receives the message to be able to respond so that the original sender sees their response. I'm having trouble finding a way to do this using the Parse twilio module.
Here is what my cloud code function looks like right now:
Parse.Cloud.define("sendText", function(request, response) {
// Use the Twilio Cloud Module to send an SMS
twilio.sendSms({
From: "+15555555555",
To: request.params.number,
Body: request.params.message
}, {
success: function(httpResponse) { response.success("SMS sent!"); },
error: function(httpResponse) { response.error("Uh oh, something went wrong"); }
});
});
Is it possible to just call this function again from its callback with the new recipient's number (the number of the original sender)?
Twilio developer evangelist here.
It seems you're trying to create what we call the masked phone numbers feature. This is a feature in which two users communicate through a central Twilio number and never find out each others' details. There is a tutorial on how to accomplish this with both calls and SMS messages however it is in Ruby on Rails. I recommend you take a read through as it gives you a good idea of how you'll need to implement this.
Then, if you have any more Parse/Node.js related questions on how to work on it, please drop me a line at philnash#twilio.com.
Check out this question/answer I posted with a similar issue.
I use Twilio to anonymize calling and texting between users of my app. There's more info in my app about how I do this, but let me know if you have some questions.
If you want to know who sent the message you need the recipient to be able to get the sender's number, so he can call the function again himself.
There are many ways to do that, your idea seems alright, you could add the sender's phone number as a parameter in the cloud function, and use it in the call back when you use sendSMS a second time.
Here is one way to do it :
Parse.Cloud.define("sendText", function(request, response) {
// Use the Twilio Cloud Module to send an SMS
twilio.sendSms({
From: "+15555555555",
To: request.params.recipientnumber, //Notice I changed the paramter name here
Body: request.params.recipientmessage //Notice I changed the paramter name here
}, {
success: function(httpResponse) {
twilio.sendSms({
From: "+15555555555",
To: request.params.sendernumber, //Notice I changed the paramter name here
Body: request.params.sendermessage //Notice I changed the paramter name here
}, {
success: function(httpResponse) {
response.success("SMS sent!");
},
error: function(httpResponse) {
response.error("Uh oh, something went wrong");
}
});
},
error: function(httpResponse) {
response.error("Uh oh, something went wrong");
}
});
});
If the first call succeeds, make another one, if that one succeeds, return success. If either fail, return failure and never start another call.
But make sure you understand this, this will pretty much send both sms at the same time, most of the time. Your sender won't get the feeling that it was a response (or it was a fast one !).
I'm not sure I understand exactly what you're trying to achieve, that's why I posted some comments to suggest something else, but I still wanted to answer here about your exact question.

Meteor 0.5.9: replacement for using Session in a server method?

So, I was attempting to do something like the following:
if(Meteor.isServer){
Meteor.methods({connect_to_api: function(vars){
// get data from remote API
return data;
}});
}
if(Meteor.isClient){
Template.myTpl.content = function(){
Meteor.call('connect_to_api', vars, function(err,data){
Session.set('placeholder', data);
});
return Session.get('placeholder');
};
}
This seemed to be working fine, but, of course, now breaks in 0.5.9 as the Session object has been removed from the server. How in the world do you now create a reactive Template that uses a server-only (stuff we don't want loading on the client) method call and get data back from that Method call. You can't put any Session references in the callback function because it doesn't exist on the server, and I don't know of any other reactive data sources available for this scenario.
I'm pretty new to Meteor, so I'm really trying to pin down best-practices stuff that has the best chance of being future-proof. Apparently the above implementation was not it.
EDIT: To clarify, this is not a problem of when I'm returning from the Template function. This is a problem of Session existing on the server. The above code will generate the following error message on the server:
Exception while invoking method 'connect_to_api' ReferenceError: Session is not defined
at Meteor.methods.connect_to_api (path/to/file.js:#:#)
at _.extend.protocol_handlers.method.exception ... etc etc
Setting the session in the callback seems to work fine, see this project I created on github: https://github.com/jtblin/meteor_session_test. In this example, I return data in a server method, and set it in the session in the callback.
There are 2 issues with your code:
1) Missing closing brace placement in Meteor.methods. The code should be:
Meteor.methods({
connect_to_api: function(vars) {
// get data from remote API
return data;
}
});
2) As explained above, you return the value in the session, before the callback is completed, i.e. before the callback method had the time to set the session variable. I guess this is why you don't see any data in the session variable yet.
I feel like an idiot (not the first time, not the last). Thanks to jtblin for showing me that Session.set does indeed work in the callback, I went back and scoured my Meteor.method function. Turns out there was one spot buried in the code where I was using Session.get which was what was throwing the error. Once I passed that value in from the client rather than trying to get it in the method itself, all was right with the world.
Oh, and you can indeed order things as above without issue.

Breezejs How to debug cause of TypeError in query response

I'm attempting to use Breeze to query a ASP.Net Web API endpoint and the query fails - with the data object containing:
internalError: TypeError
arguments: Array[2]
0: "createCtor"
1: null
length: 2
__proto__: Array[0]
get message: function () { [native code] }
get stack: function () { [native code] }
set message: function () { [native code] }
set stack: function () { [native code] }
type: "non_object_property_load"
The data object has a message (and responsetext) property which contains the full json response from the query which looks ok and the metadata thats been generated matches the response - it also records status 200 for the response
So I'm guessing there is some kind of issue mapping the response to an object on the client side?
I'm using the NuGet package for Breeze version 0.85.2
I can get the sample ToDo project to run fine on the same environment
My project does use domain objects, contexts etc all from different assemblies and namespaces but I understood thats supported in this version?
Also that one of the properties is an enum - in the metadata this is defined as {\"name\":\"State\",\"type\":\"Edm.Self.State\",\"nullable\":\"false\"}] but in the response is comes through as an integer
Looking for tips on how to debug this further on the client side
Update
comparing the working sample with my code, the error looks to be coming from this function:
/**
Returns the constructor for this EntityType.
#method getEntityCtor
#return {Function} The constructor for this EntityType.
**/
ctor.prototype.getEntityCtor = function () {
if (this._ctor) return this._ctor;
var typeRegistry = this.metadataStore._typeRegistry;
var aCtor = typeRegistry[this.name] || typeRegistry[this.shortName];
if (!aCtor) {
var createCtor = v_modelLibraryDef.defaultInstance.createCtor;
if (createCtor) {
aCtor = createCtor(this);
} else {
aCtor = function() {
};
}
}
this._setCtor(aCtor);
return aCtor;
};
The defaultInstance property on v_modelLibraryDef is undefined in my running code - what am I missing on the configuration of breeze for that to happen?
Update 2 - Resolved but why
Ok so I got this working - I was missing a reference to knockout (which I was planning to use but hadn't got that far) - I was a little bit misled by the breeze prerequisites which don't mention knockout so if anyone can explain how I could have got this working without knockout and if its a bug then the points are yours
Got same error, and referencing knockout.js helped(I'm using angularjs for my app)
manager.executeQuery(query).then(function(data) {
console.log(data);
});
But.
It seems, that data-mapper works with knockout by default, so we have XHR results as K.O. model with observables.
so I added breeze.config.initializeAdapterInstance("modelLibrary", "backingStore", true);
and now I don't receive data.results as observable collection.
Hope my answer will help.
Sorry you struggled Richard. We'll try to learn from it and spare the next person the pain you endured.
FWIW, we do not say that Knockout is a prerequisite ... because KO is not a prerequisite. You can use Angular or Backbone instead and we anticipate other alternatives in future.
We don't want to drown you in configuration options when you're just learning Breeze. So we picked KO as the default model library (just as jQuery is the default AJAX provider and Web API is the default "dataservice" technology). We say so in numerous places; prerequisites looks like another good place to mention it.
As it happens, you intended to go with KO anyway so no configuration would have been necessary. Most folks start with something like the MVC template which includes KO and loads it for you in the Index.cshtml.
Apparently you started from a clean slate ("ASP Empty Web Application" perhaps?). The Breeze Web API NuGet package strives to be spare and therefore does not include KO. We figured (incorrectly) that you would add it yourself ... in the right script order ... if you wanted to use KO. Clearly we could do a better job of documenting this particular development path ... especially as we like it so much ourselves. Thanks for pointing it out.
The other problem is that the exception was not helpful. You can see from other attempts to answer your question that even folks with Breeze experience couldn't recognize what was wrong. We'll look to see if we can detect the missing script a little earlier and throw an exception with a better message.
This error looks like it has to do with one of your Entity type constructors. I'm guessing that you are calling the 'registerEntityTypeCtor' method somewhere in your code. If so, then I would put a breakpoint in the constructor that you are registering there.
Per your other comment, .NET enums are supposed to get converted into integers on the breeze client. This is the only 'primitive' datatype that could support them. They will get converted back to enums on the server when you call 'EntityManager.saveChanges'
Breeze does not require 'knockout', you can use either 'angularjs' or 'backbone' as well. We simply default the breeze client to knockout if you do not specify another library. See the 'breeze.config.initializeAdapterInstance' topic here. We do need to a better job of documenting this.
Every time I get an error at which the Message property of the response is the data in json format means I have a bug in the function that runs after getting the data.
Example:
dataservice.getPalanca(routeData.PalancaID)
.then(function (data) {
self.palanca(data.results[0]);
})
.fail(function (error) {
console.log(error); /*if I get here and error.Message == correct json almost always means error in .then function*/
toastr.error("Ha ocurrido un error al obtener los datos");
});
I hope I help you.

Resources