In order to implement social features in an android app, I try to use the "writeMoment" method of the "PlusClient" class, but nothing happens. I am able to get a successful connection with "PlusClient" and to write deep link posts with my app.
Here is my code when I open the Google+ connection :
monPlusClient = new PlusClient.Builder(this,
new GooglePlayServicesClient.ConnectionCallbacks() {
#Override
public void onConnected() {
plusencours = false;
String accountName = monPlusClient.getAccountName();
// We've resolved any connection errors.
Toast.makeText(
ActiviteAfficher.this,
accountName
+ " "
+ ActiviteAfficher.this
.getResources()
.getString(
R.string.texteconnexion),
Toast.LENGTH_LONG).show();
// Log.d(TAG_DEBUG, accountName + " connected");
}
#Override
public void onDisconnected() {
plusencours = false;
// Log.d(TAG_DEBUG, "disconnected");
}
}, new GooglePlayServicesClient.OnConnectionFailedListener() {
#Override
public void onConnectionFailed(ConnectionResult resultat) {
if (resultat.hasResolution()) {
try {
resultat.startResolutionForResult(
ActiviteAfficher.this,
REQUEST_CODE_RESOLVE_ERR);
} catch (SendIntentException e) {
plusencours = true;
monPlusClient.connect();
}
}
// Save the result and resolve the connection failure
// upon a user click.
mConnectionResult = resultat;
}
})
.setVisibleActivities("http://schemas.google.com/AddActivity",
"http://schemas.google.com/DiscoverActivity")
.setScopes(Scopes.PLUS_LOGIN, Scopes.PLUS_PROFILE).build();
And here is my code when I use "writeMoment" :
ItemScope target = new ItemScope.Builder()
.setId(monSujet.getMid())
.setName(
monSujet.getName() + " - "
+ monSujet.getNotablename())
.setDescription(dialoguedescription).setImage(urlimage)
.setType("http://schema.org/Person").build();
Moment moment = new Moment.Builder()
.setType("http://schemas.google.com/AddActivity")
.setTarget(target).build();
if (monPlusClient.isConnected()) {
monPlusClient.writeMoment(moment);
}
Understanding the logcat is difficult for me :
05-09 12:00:32.380: I/ElegantRequestDirector(27290): I/O exception (org.apache.http.NoHttpResponseException) caught when processing request: The target server failed to respond
05-09 12:00:32.380: I/ElegantRequestDirector(27290): Retrying request
05-09 12:00:33.000: E/Volley(27290): [3428] BasicNetwork.performRequest: Unexpected response code 400 for https://www.googleapis.com/plus/v1/people/me/moments/vault
05-09 12:00:33.050: D/SyncManager(295): failed sync operation XXXXXXX#gmail.com (com.google), com.google.android.gms.plus.action, USER, earliestRunTime 140603923, SyncResult: stats [ numIoExceptions: 1]
05-09 12:00:33.050: D/SyncSetupManager(16157): setState: sync = true, wantedSyncState = true
05-09 12:00:33.090: D/SyncSetupManager(16157): Enabling sync
If you're having problems debugging issues while writing app activities, you should try enabling debug for GooglePlusPlatform:
adb shell setprop log.tag.GooglePlusPlatform VERBOSE
Which is also described here - https://developers.google.com/+/mobile/android/getting-started#frequently_asked_questions
Running your code with debugging enabled writes the following to logcat:
D/GooglePlusPlatform(8133): Unexpected response code (400) when requesting: writeMoment
D/GooglePlusPlatform(8133): Error response: {
D/GooglePlusPlatform(8133): "error": {
D/GooglePlusPlatform(8133): "errors": [
D/GooglePlusPlatform(8133): {
D/GooglePlusPlatform(8133): "domain": "global",
D/GooglePlusPlatform(8133): "reason": "badRequest",
D/GooglePlusPlatform(8133): "message": "Missing metadata field: http://schema.org/url."
D/GooglePlusPlatform(8133): }
D/GooglePlusPlatform(8133): ],
D/GooglePlusPlatform(8133): "code": 400,
D/GooglePlusPlatform(8133): "message": "Missing metadata field: http://schema.org/url."
D/GooglePlusPlatform(8133): }
D/GooglePlusPlatform(8133): }
You cannot supply a Person object without supplying a public target URL which has appropriate markup (instead of an explicit name and description). Running your code with http://schema.org/Thing instead of http://schema.org/Person worked for me.
Related
I am trying to get the card token to proceed with Mercado Pago transparent checkout.
Below is the code I am using to request the card token:
CardToken cardToken = new CardToken("5031433215406351",11,2025,"123","Test","CPF","49647428065");
new MercadoPagoServices(getContext(), MERCADOPAGO_SANDBOX_PUBLIC_KEY,"").createToken(cardToken, new Callback<Token>() {
#Override
public void success(Token token) {
Log.i(TAG, "success: MercadoPago token: "+token);
}
#Override
public void failure(ApiException apiException) {
Log.i(TAG, "failure: MercadoPago message: "+apiException.getMessage());
Log.i(TAG, "failure: MercadoPago error: "+apiException.getError());
}
});
Below is log:
MainFragment: failure: MercadoPago message: an error occurred doing POST card_token
MainFragment: failure: MercadoPago error: internal_error
It is important to mention that I am not looking for the suggested way of doing payments, which is creating a preference and later starting payment.
So my question is:
What is the proper manner of getting the Mercado Pago card token in Android?
this is my code
try {
if (AWSIotKeystoreHelper.isKeystorePresent(keystorePath, keystoreName)) {
if (AWSIotKeystoreHelper.keystoreContainsAlias(certificateId, keystorePath,
keystoreName, keystorePassword)) {
Log.i(LOG_TAG, "Certificate " + certificateId
+ " found in keystore - using for MQTT.");
// load keystore from file into memory to pass on connection
clientKeyStore = AWSIotKeystoreHelper.getIotKeystore(certificateId,
keystorePath, keystoreName, keystorePassword);
btnConnect.setEnabled(true);
mqttManager.setAutoReconnect(false);
} else {
Log.i(LOG_TAG, "Key/cert " + certificateId + " not found in keystore.");
}
} else {
Log.i(LOG_TAG, "Keystore " + keystorePath + "/" + keystoreName + " not found.");
}
} catch (Exception e) {
Log.e(LOG_TAG, "An error occurred retrieving cert/key from keystore.", e);
}
if (clientKeyStore == null) {
Log.i(LOG_TAG, "Cert/key was not found in keystore - creating new key and certificate.");
new Thread(new Runnable() {
#Override
public void run() {
try {
// Create a new private key and certificate. This call
// creates both on the server and returns them to the
// device.
CreateKeysAndCertificateRequest createKeysAndCertificateRequest =
new CreateKeysAndCertificateRequest();
createKeysAndCertificateRequest.setSetAsActive(true);
final CreateKeysAndCertificateResult createKeysAndCertificateResult;
createKeysAndCertificateResult =
mIotAndroidClient.createKeysAndCertificate(createKeysAndCertificateRequest);
Log.i(LOG_TAG,
"Cert ID: " +
createKeysAndCertificateResult.getCertificateId() +
" created.");
// store in keystore for use in MQTT client
// saved as alias "default" so a new certificate isn't
// generated each run of this application
AWSIotKeystoreHelper.saveCertificateAndPrivateKey(certificateId,
createKeysAndCertificateResult.getCertificatePem(),
createKeysAndCertificateResult.getKeyPair().getPrivateKey(),
keystorePath, keystoreName, keystorePassword);
// load keystore from file into memory to pass on
// connection
clientKeyStore = AWSIotKeystoreHelper.getIotKeystore(certificateId,
keystorePath, keystoreName, keystorePassword);
// Attach a policy to the newly created certificate.
// This flow assumes the policy was already created in
// AWS IoT and we are now just attaching it to the
// certificate.
AttachPrincipalPolicyRequest policyAttachRequest =
new AttachPrincipalPolicyRequest();
policyAttachRequest.setPolicyName(AWS_IOT_POLICY_NAME);
policyAttachRequest.setPrincipal(createKeysAndCertificateResult
.getCertificateArn());
mIotAndroidClient.attachPrincipalPolicy(policyAttachRequest);
runOnUiThread(new Runnable() {
#Override
public void run() {
btnConnect.setEnabled(true);
}
});
} catch (Exception e) {
Log.e(LOG_TAG,
"Exception occurred when generating new private key and certificate.",
e);
}
}
}).start();
}
}
View.OnClickListener connectClick = new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(LOG_TAG, "clientId = " + clientId);
try {
mqttManager.connect(clientKeyStore, new AWSIotMqttClientStatusCallback() {
#Override
public void onStatusChanged(final AWSIotMqttClientStatus status,
final Throwable throwable) {
Log.d(LOG_TAG, "Status = " + String.valueOf(status));
runOnUiThread(new Runnable() {
#Override
public void run() {
if (status == AWSIotMqttClientStatus.Connecting) {
tvStatus.setText("Connecting...");
} else if (status == AWSIotMqttClientStatus.Connected) {
tvStatus.setText("Connected");
} else if (status == AWSIotMqttClientStatus.Reconnecting) {
if (throwable != null) {
Log.e(LOG_TAG, "Connection error.", throwable);
}
tvStatus.setText("Reconnecting");
} else if (status == AWSIotMqttClientStatus.ConnectionLost) {
if (throwable != null) {
Log.e(LOG_TAG, "Connection error.", throwable);
}
tvStatus.setText("Disconnected");
} else {
tvStatus.setText("Disconnected");
}
}
});
}
});
} catch (final Exception e) {
Log.e(LOG_TAG, "Connection error.", e);
tvStatus.setText("Error! " + e.getMessage());
}
}
};
when i'm trying to connect with aws iot mqtt broker using android phone i got error as under:
E/com.amazonaws.demo.androidpubsub.PubSubActivity: Connection error.
Connection lost (32109) - java.io.EOFException
at org.eclipse.paho.client.mqttv3.internal.CommsReceiver.run(CommsReceiver.java:146)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.io.EOFException
at java.io.DataInputStream.readByte(DataInputStream.java:77)
at org.eclipse.paho.client.mqttv3.internal.wire.MqttInputStream.readMqttWireMessage(MqttInputStream.java:65)
at org.eclipse.paho.client.mqttv3.internal.CommsReceiver.run(CommsReceiver.java:107)
at java.lang.Thread.run(Thread.java:818)
The above exception can be due to variety of reasons such as loss of network connectivity, policy restrictions to connect or subscribe etc. Unfortunately, Mqtt paho client does not always propagate the connectivity exceptions perfectly and so it might be difficult to root cause the issue just from this exception. It seems you are following this sample app. I was able to get the app working with the README instructions. Following are some of the points that I suspect might cause this issue:
Ensure that the following IAM Policy is attached to the unauthenticated role created as part of the Identity Pool creation
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iot:AttachPrincipalPolicy",
"iot:CreateKeysAndCertificate"
],
"Resource": [
"*"
]
}
]
}
Ensure that the following IoT Policy is attached to the device certificate
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "iot:Connect",
"Resource": ""
},
{
"Effect": "Allow",
"Action": [
"iot:Publish",
"iot:Subscribe",
"iot:Receive"
],
"Resource": ""
}
]
}
Hope it helps!
As already suggested, the problem is almost certainly due to not having an appropriate policy attached, but this is further complicated by poor error handling in the AWS sample code. The code above first looks in the device keystore for a saved certificate and, if found, tries to connect using it. If it cannot find a certificate under the expected keystore name, it then creates a new certificate, saves it in the keystore, and then tries to attach the principle policy to it. If anything goes wrong getting the policy from AWS, then you are left with an incorrectly configured entry in the keystore and the code as supplied by AWS can never recover from that. I had spent many hours experimenting with policies without success until I actually traced through the code and realised that it made no difference what policy I specified - the code was ignoring it and using the incorrectly configured policy in the keystore!
In the catch block in the code above, add the following
AWSIotKeystoreHelper.deleteKeystoreAlias(certificateId,
keystorePath, keystoreName, keystorePassword);
That will ensure that there is no incorrectly configured certificate hanging around to trip you up.
As far as the initial error is concerned, the problem is probably the name and context of the policy that you specified. I created policies in IAM and they were not recognised - you actually need to create the IoT policy as described above by Roshan within the context of IoT Core Security and specify the name that you give it within the PubSub sample code.
I have the the authenticated user with federated ID. But when I try to access the AWS IOT stuff I get this error which is driving me crazy.
I am following the iot sample code. All the relevant credentials are correct too.
`MQTTHelper`
....
credentialsProvider = new CognitoCachingCredentialsProvider(
mContext.getApplicationContext(), // context
BuildConfig.COGNITO_POOL_ID, // Identity Pool ID
MY_REGION // Region
);
Region region = Region.getRegion(MY_REGION);
mqttManager = new AWSIotMqttManager(clientId, BuildConfig.CUSTOMER_SPECIFIC_ENDPOINT);
mqttManager.setKeepAlive(10);
mAwsIotDataClient = new AWSIotDataClient(credentialsProvider);
String iotDataEndpoint = BuildConfig.CUSTOMER_SPECIFIC_ENDPOINT;
mAwsIotDataClient.setEndpoint(iotDataEndpoint);
mAwsIotDataClient.setRegion(region);
// mqttManager.setMqttLastWillAndTestament(lwt);
mIotAndroidClient = new AWSIotClient(credentialsProvider);
mIotAndroidClient.setRegion(region);
keystorePath = mContext.getFilesDir().getPath();
keystoreName = BuildConfig.KEYSTORE_NAME;
keystorePassword = BuildConfig.KEYSTORE_PASSWORD;
certificateId = BuildConfig.CERTIFICATE_ID;
// To load cert/key from keystore on filesystem
try {
if (AWSIotKeystoreHelper.isKeystorePresent(keystorePath, keystoreName)) {
if (AWSIotKeystoreHelper.keystoreContainsAlias(certificateId, keystorePath,
keystoreName, keystorePassword)) {
Log.d(LOG_TAG, "Certificate " + certificateId
+ " found in keystore - using for MQTT.");
// load keystore from file into memory to pass on connection
clientKeyStore = AWSIotKeystoreHelper.getIotKeystore(certificateId,
keystorePath, keystoreName, keystorePassword);
//btnConnect.setEnabled(true);
Log.i(LOG_TAG, "Connected....");
//CONNECTED_TO_DEVICE = true;
} else {
Log.i(LOG_TAG, "Key/cert " + certificateId + " not found in keystore.");
}
} else {
Log.i(LOG_TAG, "Keystore " + keystorePath + "/" + keystoreName + " not found.");
}
} catch (Exception e) {
Log.e(LOG_TAG, "An error occurred retrieving cert/key from keystore.", e);
}
if (clientKeyStore == null) {
IS_CERTIFICATE_GENERATED = false;
Log.i(LOG_TAG, "Cert/key was not found in keystore - creating new key and certificate.");
doGenerateNewCertificate();
} else {
IS_CERTIFICATE_GENERATED = true;
doMqttConnect();
}
}
private static void doMqttConnect() {
Log.d(LOG_TAG, "clientId = " + clientId);
try {
mqttManager.connect(clientKeyStore, new AWSIotMqttClientStatusCallback() {
#Override
public void onStatusChanged(final AWSIotMqttClientStatus status,
final Throwable throwable) {
Log.d(LOG_TAG, "Status = " + String.valueOf(status));
if (mqttManagerConnStatus != null) {
//Send Mqtt Manager Status Back
mqttManagerConnStatus.onStatusChanged(status, throwable);
}
}
});
} catch (final Exception e) {
Log.e(LOG_TAG, "Connection error.", e);
}
and similarly as mentioned in the sample code I am calling GetShadow() in another class
GetThingShadowRequest getThingShadowRequest = new GetThingShadowRequest() .withThingName(thingName);
GetThingShadowResult result = mDashboard.mqttHelper.doGetAwsIotDataClient()
.getThingShadow(getThingShadowRequest);
byte[] bytes = new byte[result.getPayload().remaining()];
result.getPayload().get(bytes);
String resultString = new String(bytes);
return new AsyncTaskResult<String>(resultString);
I am able to get the KMS working so there is no problem with the authenticated (federated Id). The only source of information I get on AWS IOT is just this which is not helpful from client perspective.
Is it the issue with the AWS IOT configuration or code issue? I have to subscribe to the Thing Group, is there anything else I need to do to subscribe to the group?
This is the Thing Group ARN that I needs to subscribe to
arn:aws:iot:us-east-1:XXXXXXXXXX:thinggroup/A_GROUP
Stack Trace
getShadowTask
com.amazonaws.AmazonServiceException: null (Service: AWSIotData; Status Code: 403; Error Code: ForbiddenException; Request ID: f78eea4d-9053-4b19-1840-297dd67c2667)
at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.java:730)
at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:405)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:212)
at com.amazonaws.services.iotdata.AWSIotDataClient.invoke(AWSIotDataClient.java:571)
at com.amazonaws.services.iotdata.AWSIotDataClient.getThingShadow(AWSIotDataClient.java:406)
at com.lyrebird.abc.device.MyDevicesFragment_RV_Adapter$GetShadowTask.doInBackground(MyDevicesFragment_RV_Adapter.java:519)
at com.lyrebird.abc.device.MyDevicesFragment_RV_Adapter$GetShadowTask.doInBackground(MyDevicesFragment_RV_Adapter.java:497)
at android.os.AsyncTask$2.call(AsyncTask.java:295)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
06-18 06:00:54.029 7489-7489/com.lyrebird.abc E/com.lyrebird.abc.device.MyDevicesFragment_RV_Adapter.GetShadowTask: getShadowTask
com.amazonaws.AmazonServiceException: null (Service: AWSIotData; Status Code: 403; Error Code: ForbiddenException; Request ID: f78eea4d-9053-4b19-1840-297dd67c2667)
at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.java:730)
at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:405)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:212)
at com.amazonaws.services.iotdata.AWSIotDataClient.invoke(AWSIotDataClient.java:571)
at com.amazonaws.services.iotdata.AWSIotDataClient.getThingShadow(AWSIotDataClient.java:406)
at com.lyrebird.abc.device.MyDevicesFragment_RV_Adapter$GetShadowTask.doInBackground(MyDevicesFragment_RV_Adapter.java:519)
at com.lyrebird.abc.device.MyDevicesFragment_RV_Adapter$GetShadowTask.doInBackground(MyDevicesFragment_RV_Adapter.java:497)
at android.os.AsyncTask$2.call(AsyncTask.java:295)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iot:*",
"lambda:*"
],
"Resource": [
"*"
]
}
]
}
Here are the few reasons why you might be getting error 403
In Cognito, there are no appropriate permissions for Update/Get Shadow both for authenticated and unauthenticated pool
The ARN of the Cognito Pool id as well as the IoT are incorrect
Check the IAM policy and the following policy to the Cognito users, Also for the Cognito user, you have to attach AttachPrincipalPolicy policy to give them appropriate permissions for Get/update the shadow. The policy below should be in the Cognito Auth and UnAuth roles.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iot:AttachPrincipalPolicy"
],
"Resource": [
"*"
]
}
] }
I am using Retrofit 2.1.0 with Jackson to make an API call.
The remote api gives two different response one which has json object with string and one custom object. and another response cary only status and error message.like below
required response
{
"status": "success",
"data": {
"id": 79068,
"username": "neha.fren01#gmail.com",
"email": "neha.fren01#gmail.com",
"enabled": false,
"confirmation_token": "27090745",
"name": "ronem",
"premium": false,
"token": "nmdgZe5Put6kS1KC_KH5d8Tk-fZLxZ15bV5tahJwQlY",
"phone_verified": false,
"email_verified": false
}
}
error response
{
"status": "error",
"message": "Unable to create userERROR: Email you entered is invalid. Provide another email.\n"
}
I can handle the required response shown above.but cannot handle the error response.
Here is the code how I made call
call.enqueue(new Callback<RegisteredResponse>() {
#Override
public void onResponse(Call<RegisteredResponse> call, Response<RegisteredResponse> response) {
if (response.isSuccessful()) {
try {
EventBus.post(new Events.RegistrationResponseEvent(StaticStorage.REGISTRATION_IDENTIFIER, response.body()));
} catch (Exception e) {
e.printStackTrace();
// EventBus.post(new Events.ErrorEvent(StaticStorage.REGISTRATION_IDENTIFIER, response.errorBody().toString()));
}
}else{
// I want to handle error response here.but error response is present inside response.isSuccessful() block
}
}
#Override
public void onFailure(Call<RegisteredResponse> call, Throwable t) {
t.printStackTrace();
EventBus.post(new Events.ErrorEvent(StaticStorage.REGISTRATION_IDENTIFIER, StaticStorage.ERROR_IN_LOADING));
}
});
Even the response object is error response it always goes to
response.isSuccessful()
block
I am unable to solve this issue. I lost 2 hours searching solution.
I followed this link aswell
response.isSuccessful()
Retrofit is depend on what status code you are getting from the server. even in failure if server still sending you 200 responseCode then there is no way you will get it in onError
means your api call was successful and response came. Doesn't matter what response came from server. For that you have to manually parse response and check whether your Json object has error or success status.
As per my opinion you have to make the response universal for all the web service. like
Sucess
{
"status": true,
"data": {
"id": 79068,
"username": "neha.fren01#gmail.com",
"email": "neha.fren01#gmail.com",
"enabled": false,
"confirmation_token": "27090745",
"name": "ronem",
"premium": false,
"token": "nmdgZe5Put6kS1KC_KH5d8Tk-fZLxZ15bV5tahJwQlY",
"phone_verified": false,
"email_verified": false
}
"message": ""
}
Error
{
"status": false,
"data":{},
"message": "Unable to create userERROR: Email you entered is invalid. Provide another email.\n"
}
Please change to status boolean flag, you have to check status of the response. If it is true then response is sucessfull if false then there is some error in response.
response.isSuccessful()
instead of above you need to check the status code of the server response, if it is 200 then web service sucessfully called.
I'm picking up a project from last year that was based on the now discontinued 'mobile backend starter' from Google. I believe the app was left in a working state but it now seems to fail the authentication when the "Secured by Client IDs" setting is selected on the web page google provided. I get the following error:
com.google.api.client.googleapis.json.GoogleJsonResponseException: 401 Unauthorized
{
"code": 401,
"errors": [
{
"domain": "global",
"location": "Authorization",
"locationType": "header",
"message": "Unauthenticated calls are not allowed",
"reason": "required"
}
],
"message": "Unauthenticated calls are not allowed"
}
The error results from running this method
private void listPosts(final String alertTxt) {
// create a response handler that will receive the result or an error
CloudCallbackHandler<List<CloudEntity>> handler =
new CloudCallbackHandler<List<CloudEntity>>() {
#Override
public void onComplete(List<CloudEntity> results) {
//mAnnounceTxt.setText(R.string.announce_success);
mAnnounceTxt.setText(alertTxt);
mPosts = results;
animateArrival();
updateGuestbookView();
}
#Override
public void onError(IOException exception) {
mAnnounceTxt.setText(R.string.announce_fail);
animateArrival();
handleEndpointException(exception);
}
};
...
I am not really sure where/how to start debugging this?
401 Errors are usually caused by any of the following:
Expired token
Token revocation
Token not authorized for needed scopes
Request not authorized correctly with OAuth
Try refreshToken() to resolve expired token issues