Google Proximity Beacon API gives 403 unauthorised error - android

I am trying to consume Google's Beacon Proximity api. i have followed following steps to integrate them:
1) Signed up on Google Api Console.
2) Created new Project.
3) enabled Beacon proximity api and Nearby Api.
4) Generated Api key from Credentials.
Afterwards i invoke the following api:
{
"advertisedId": {
"type": "EDDYSTONE",
"id": "ABEiM0RVZneImaq7zN3u/w=="
},
"status": "ACTIVE",
"placeId": "ChIJL_P_CXMEDTkRw0ZdG-0GVvw",
"latLng": {
"latitude": "71.6693771",
"longitude": "-22.1966037"
},
"indoorLevel": {
"name": "1"
},
"expectedStability": "STABLE",
"description": "An example beacon.",
"properties": {
"position": "entryway"
}
}
with the follwing url:
https://proximitybeacon.googleapis.com/v1beta1/beacons:register?key=xxxx(my_api_key)
but the response says:
{
"error": {
"code": 403,
"message": "Unauthorized.",
"status": "PERMISSION_DENIED"
}
}
what is it that i am missing..
I also tried to use Beacon tools app but after entering EID and all other credentials..the App crashes(on android), while it is not able to connect to my eddystone on Ios.

Found the Solution, API_KEY can be used only to Access already registered beacons and their Characteristics, while to Register and update we require ClientId and client Secret key and you can register it in OAuth2.0 Playground.
it worked for me ;)

You can Get a service token after creating an account service key on the google API Console. Then generate it with this code:
String token = null;
try{
GoogleCredential credential = GoogleCredential.fromStream(accesKey).createScoped
(Collections.singleton("https://www.googleapis.com/auth/userlocation.beacon.registry"));
credential.refreshToken();
token = credential.getAccessToken();
} catch (FileNotFoundException ex) {
Logger.getLogger(BeaconRegisterClass.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(BeaconRegisterClass.class.getName()).log(Level.SEVERE, null, ex);
}
Then put it on the header of your call:
key: Authorization value: Bearer (your token here)
set the body of this call as beacon.json

Related

how to access added parameter in branch deep linking

This question is not a duplication of this question.I have tried the solution mentioned there but didn't get any luck.
I have added branch.io deep-linking to my app. To test the implementation I have created a link with parameter as described here
https://docs.branch.io/pages/apps/android/#test-deep-link
everything worked fine, but the problem is I can not access the added data from the json object as the json doesn't contain the key I added earlier. I was supposed to get a response like this:
{
"identity_id": "427469360685348303",
"link": "https://example.app.link?%24identity_id=427469360685348303",
"session_id": "429691081177874743",
"data": {
"$canonical_identifier": "item/1503684554354.28",
"$desktop_url": "http://example.com/home",
"$exp_date": 0,
"$identity_id": "427469360685348303",
"$og_description": "My Content Description",
"$og_image_url": "http://lorempixel.com/200/200/",
"$og_title": "46D6D28E-0390-40E4-A856-BD74F34D24C8",
"$publicly_indexable": 1,
"+click_timestamp": 1503684563,
"+clicked_branch_link": true,
"+is_first_session": false,
"+match_guaranteed": true,
"custom": "blue",
"random": "FE848A5B-78F7-42EC-A253-9F795FE91692",
"added": "1503684554354.33",
"~campaign": "new launch",
"~channel": "facebook",
"~creation_source": 3,
"~feature": "sharing",
"~id": 429691043152332059,
"~referring_link": "https://example.app.link/X7OsnWv9TF",
"~stage": "new person",
"~tags": [
"one",
"two"
]
}
}
But this the response I got:
{"+non_branch_link":"https:\/\/qr6x.test-app.link\/g5ynWCX7PI","+clicked_branch_link":false,"+is_first_session":false}
here is my code:
Branch branch = Branch.getInstance(context);
branch.initSession(new Branch.BranchReferralInitListener() {
#Override
public void onInitFinished(JSONObject referringParams, BranchError error) {
if (error == null) {
// params are the deep linked params associated with the link that the user clicked -> was re-directed to this app
// params will be empty if no data found
// ... insert custom logic here ...
try {
Log.e("myapp","no error");
Log.e("myapp", referringParams.toString());
String pictureID = referringParams.optString("asdasdasdasd", "");
if (pictureID.equals("")) {
Log.e("myapp","no ID");
}
else {
Log.e("myapp","ID "+pictureID);
}
} catch (Exception e) {
System.out.println(" " + e.toString());
}
} else {
Log.i("MyApp", error.getMessage());
}
}
}, intent.getData(), activity);
can anyone give any idea what I am doing wrong?
Jackie from Branch here.
The +non_branch_link typically happens whenever there is an error when creating a Branch Deep Link, or whenever the live_key/test_key get mixed up (i.e. clicking a test link with an app that's using your live key, or vice versa).
Can you confirm that you have the correct Branch test key in the AndroidManifest.xml of your staging app? Here's our documentation on Android app config.
If you continue to experience issues, feel free to send over your APK file to integrations#branch.io and I'd be happy to investigate further for you.

Different objects but still goes inside if condition of response.isSuccessfull() in Retrofit 2.1.0

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.

YouTube Data API v3 Authentification Error

I'm trying to access the YouTube Data API v3 from within my app to fetch some videos from a specific channnel. I created an API Key and inserted my package name and the SHA-1 fingerprint. However, it does not work.
This is the error:
com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden
{
"code" : 403,
"errors" : [ {
"domain" : "usageLimits",
"message" : "The Android package name and signing-certificate fingerprint, null and null, do not match the app restrictions configured on your API key. Please use the API Console to update your key restrictions.",
"reason" : "ipRefererBlocked",
"extendedHelp" : "https://console.developers.google.com/apis/credentials?project=1097633804344"
} ],
"message" : "The Android package name and signing-certificate fingerprint, null and null, do not match the app restrictions configured on your API key. Please use the API Console to update your key restrictions."
}
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:113)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:40)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest$1.interceptResponse(AbstractGoogleClientRequest.java:321)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1065)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)
at de.axelrindle.youtubeapitest.YoutubeConnector.fetchVideoIDS(YoutubeConnector.java:59)
at de.axelrindle.youtubeapitest.util.VideoIDFetcher.fetchVideoIDS(VideoIDFetcher.java:62)
at de.axelrindle.youtubeapitest.InitService.onHandleIntent(InitService.java:57)
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:66)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.os.HandlerThread.run(HandlerThread.java:61)
And here is the code, which sends the request:
YoutubeConnector.class
public YoutubeConnector(Context context) {
this.context = context;
youTube = new YouTube.Builder(new NetHttpTransport(), new JacksonFactory(), new HttpRequestInitializer() {
#Override
public void initialize(HttpRequest request) throws IOException {}
}).setApplicationName("YouTube Data API v3 Test").build();
try {
query = youTube.search().list("id,snippet");
query.setKey(DevKey.YOUTUBE_API);
query.setType("video");
query.setFields("items(id/videoId,snippet/title,snippet/description,snippet/thumbnails/default/url)");
query.setChannelId("UC3ifTl5zKiCAhHIBQYcaTeg");
query.setMaxResults(maxResults);
} catch (IOException e) {
Log.e("YoutubeConnector", "Failed to connect to YouTube: " + e.getMessage());
}
}
public List<String> fetchVideoIDS() {
List<String> ids = new ArrayList<>();
maxResults += 10;
try {
SearchListResponse response = query.execute();
List<SearchResult> results = response.getItems();
for (SearchResult result : results) {
ids.add(result.getId().getVideoId());
}
} catch (IOException e) {
e.printStackTrace();
}
return ids;
}
Any help is MUCH appreciated!
Fixed it by myself.
I was just using the wrong API key.
EDIT:
Maybe I should mention that it worked when I used an browser api key instead of an android api key.

Life post Android Mobile Backend Starter? Authentication errors

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

Google drive SDK 2.0 throws error 400 Bad Request

I've been fighting with Google Drive API for Android for more than 50 hours now, and have not come one inch closer. From my understanding, there are 1001 ways to access Google drive (Google Docs API, REST & Google Drive SDK v2). I'm using Google Drive SDK v2. I want want to access Google Drive to upload jpeg files. Platform, Android 2.2+.
What I've tried:
Using the recently released SDK:
http://code.google.com/p/google-api-java-client/wiki/APIs#Drive_API
I've watched the Google I/O sesssion, but the most important part (how to create a Drive object using your Client ID & Client Secret) was left out:
https://developers.google.com/events/io/sessions/gooio2012/705/
I have created multiple keys on https://code.google.com/apis/console. The last one I've created (and tested with) was created using "Create another client ID..." -> "Installed Application" -> "Android". I've used the key in the ~/.android/debug.keystore.
I've also tried to create a key for an "Other" (instead of Android/iOS) installed app, but this gives me a Client ID and Client secret. It seems like the Drive object does not accept a client secret.
Where the code says "1234567890-abcdefghij123klmnop.apps.googleusercontent.com", I've tried to use both "API key" and the "Client ID", both gave the same error.
My code:
Account account = AccountManager.get(context).getAccountsByType(
"com.google")[0];
String token;
try {
token = GoogleAuthUtil.getToken(context, account.name, "oauth2:"
+ DriveScopes.DRIVE_FILE);
} catch (UserRecoverableAuthException e) {
context.startActivityForResult(e.getIntent(), ASK_PERMISSION);
return;
} catch (IOException e) {
return;
} catch (GoogleAuthException e) {
return;
}
HttpTransport httpTransport = new NetHttpTransport();
JacksonFactory jsonFactory = new JacksonFactory();
Drive.Builder b = new Drive.Builder(httpTransport, jsonFactory, null);
final String tokenCopy = token;
b.setJsonHttpRequestInitializer(new JsonHttpRequestInitializer() {
public void initialize(JsonHttpRequest request) throws IOException {
DriveRequest driveRequest = (DriveRequest) request;
driveRequest.setPrettyPrint(true);
driveRequest
.setKey("1234567890-abcdefghij123klmnop.apps.googleusercontent.com");
driveRequest.setOauthToken(tokenCopy);
}
});
final Drive drive = b.build();
FileList files;
try {
files = drive.files().list().setQ("mimeType=text/plain").execute();
} catch (IOException e) {
e.printStackTrace(); // throws HTTP 400
}
The error I'm getting is:
com.google.api.client.googleapis.json.GoogleJsonResponseException: 400 Bad Request
{
"code" : 400,
"errors" : [ {
"domain" : "global",
"location" : "q",
"locationType" : "parameter",
"message" : "Invalid Value",
"reason" : "invalid"
} ],
"message" : "Invalid Value"
}
As the error message suggests, your error is in the query parameter q. The correct syntax for your q parameter is
files = drive.files().list().setQ("mimeType='text/plain'").execute();
and not :
files = drive.files().list().setQ("mimeType=text/plain").execute();
Looking at your code, you are fully authenticated and your request is failing because of this syntax error.

Categories

Resources