Google fit offline - access token issue - google-api

Hi Everyone i facing one strange issue from long time with few accounts while syncing google fit data for few users.
We have followed below document for offline-access of google fit - https://developers.google.com/identity/sign-in/android/offline-access
Step 1 - get access token (Here we are refreshing token as when require), In this step we are getting error
400 Bad Request POST https://oauth2.googleapis.com/token { "error" : "invalid_grant", "error_description" : "Bad Request" }
public String getAccessToken(ThirdPartyAuthDto r) throws Exception {
GoogleClientSecrets clientSecrets = getGoogleClient();
// request token
if (r.getRefreshToken() == null || (r.getRefreshToken() != null && r.getRefreshToken().length() == 0)) {
GoogleTokenResponse activeUser = new GoogleAuthorizationCodeTokenRequest(new NetHttpTransport(),
new JacksonFactory(), "https://oauth2.googleapis.com/token",
clientSecrets.getDetails().getClientId(), clientSecrets.getDetails().getClientSecret(),
r.getServerAuthCode(), "").execute();
r.setAccessToken(activeUser.getAccessToken());
r.setTokenType(activeUser.getTokenType());
r.setExpiresInSeconds(activeUser.getExpiresInSeconds());
r.setRefreshToken(activeUser.getRefreshToken());
r.setScope(activeUser.getScope());
r.setLastRequestDate(new Date());
r.setLastRequestSuccessDate(new Date(new Date().getTime() - (5 * 60000)));
thirdPartyRepository.save(r);
return activeUser.getAccessToken();
} else {
boolean tokenRequest = true;
if (r.getLastRequestSuccessDate() != null
&& new Date().before(new Date(r.getLastRequestSuccessDate().getTime() + r.getExpiresInSeconds() * 1000))){
tokenRequest = false;
}
if(tokenRequest) {
TokenResponse tokenResponse = refreshAccessToken(r.getRefreshToken(), clientSecrets.getDetails().getClientId(), clientSecrets.getDetails().getClientSecret());
r.setAccessToken(tokenResponse.getAccessToken());
r.setLastRequestSuccessDate(new Date(new Date().getTime() - (5 * 60000)));
r.setExpiresInSeconds(tokenResponse.getExpiresInSeconds());
thirdPartyRepository.save(r);
return tokenResponse.getAccessToken();
}else{
return r.getAccessToken();
}
}
}
public TokenResponse refreshAccessToken(String refreshToken, String clientId, String clientSecrets) throws IOException {
TokenResponse response = new GoogleRefreshTokenRequest(
new NetHttpTransport(),
new JacksonFactory(),
refreshToken,
clientId,
clientSecrets)
.execute();
System.out.println("Access token: " + response.getAccessToken());
return response;
}

Getting invalid grant when using a refresh token normally means that the refresh token is expired or was revoked.
Possible reasons for expired refresh tokens.
the user has revoked your access
you have more then 50 outstanding refresh tokens for this user
The app is still in the testing phase which means refresh tokens expire after seven days.

Related

Can we pass the Object in the GET Request in spring boot?

When i pass the body in the GET request to the below api its throwing the 400 bad request.if i pass through the Feign client its throwing method not found it is internally converting GET reuest to POST request, Can u please suggest what are the possible ways i can do? except from changing the request to POST
Api
#GetMapping("/users")
#ApiOperation(value = "Retrieve users by role names list", notes = "Retrieves users by role name or role names passed in the list")
#ApiResponses(value = { #ApiResponse(code = 404, message = "ROLE_NOT_FOUND") })
public PagedResources<Resource<UserResponse>> retrieveUsersByRoleNames(#RequestBody RoleNameRequest roleNameRequest,
#RequestParam(name = "includeLocked", required = false) Boolean locked,
#RequestParam(name = "excludeUserId", required = false) String userId,
#RequestParam(name = "includeDeleted", required = false) Boolean isDeleted,
Pageable page,
PagedResourcesAssembler<UserResponse> pagedAssembler) {
Subscription subscription = serviceUtility.fetchSubscription();
Page<UserResponse> pageUserResponse = roleService.findAllByRoleNames(roleNameRequest, locked, isDeleted, userId, subscription,page)
.map(userAttribute -> ModelConverter.modelResponse(userAttribute, true));
log.info("pageUserResponse : " + pageUserResponse);
log.info("pageUserResponse.getTotalElements() : " + pageUserResponse.getTotalElements());
log.info("page details size for roleNames list: " + pageUserResponse.getContent().size());
log.info("page details values for roleNames list: " + pageUserResponse.getContent().toString());
return pagedAssembler.toResource(pageUserResponse);
}
Request
RoleNameRequest roleNameRequest = new RoleNameRequest();
roleNameRequest.setRoleNames(identity.getPrimaryRoles());
List<UserResponseWithWorkload> usersWithWorkload = null;
try {
log.info("Pager Details : " + pageable.toString());
log.info("subscriptionId : " + subscriptionId);
causing exception -> resources = securityServiceFeignClient.retrieveUsersByMultipleRoles(roleNameRequest,
subscriptionId, pageable.getPageNumber(), pageable.getPageSize(),userId);
usersWithWorkload = getUsersWithWorkload(resources.getContent().toArray(),
workload, identity.getActivityId(), identity.getAssignmentMode());
log.info(" Resource from security service : " + resources.getContent().toString());
log.info(" Resource size from security service : " + resources.getContent().size());
log.info(" Resource array from security service : " + resources.getContent().toArray());
} catch (Exception e) {
log.error(e.getMessage(), e);
}
Try using #ModelAttribute annotation
#ModelAttribute("myObject") MyObject myObject

Google places API counts about 22 times more than 1 request

I recently noticed that I'm getting about 22 times the requests as I should be getting on the Google API console which let to some unexpected charges. Below is the code I am using to get details about hospitals near an area. I need the name and street address.
GeoApiContext context = new GeoApiContext.Builder().apiKey("MYAPIKEY")
.build();
NearbySearchRequest req = PlacesApi.nearbySearchQuery(context,
new com.google.maps.model.LatLng(Double.valueOf(lat), Double.valueOf(lon)));
PlacesSearchResponse resp = req.keyword("hospital").type(PlaceType.HOSPITAL).radius(42000).await();
if (resp.results != null && resp.results.length > 0) {
for (PlacesSearchResult r : resp.results) {
try {
PlaceDetails placeDetails = PlacesApi.placeDetails(context, r.placeId).await();
AddressComponent[] address = placeDetails.addressComponents;
} catch (com.google.maps.errors.NotFoundException nfe) {
}
}
}
What is causing this to register about 22 times more requests?

Using LinqToTwitter in Console App and getting AggregateException Error

I'm trying to do a basic SingleUserAuthorizer call to twitter. I am getting this Exception when I try the User Linq request. Any ideas?
Exception thrown: 'System.AggregateException' in mscorlib.dll
var auth = new SingleUserAuthorizer
{
CredentialStore = new SingleUserInMemoryCredentialStore
{
ConsumerKey = twitterConsumerKey,
ConsumerSecret = twitterConsumerSecret,
OAuthToken = twitterAccessTokenSecret,
AccessToken = twitterAccessToken
}
};
//await auth.AuthorizeAsync();
var twitterCtx = new TwitterContext(auth);
User user =
(from tweet in twitterCtx.User
where tweet.Type == UserType.Show &&
tweet.ScreenName == member.screenName
select tweet)
.SingleOrDefault();
We resolved the issue via this discussion on GitHub:
https://github.com/JoeMayo/LinqToTwitter/issues/45

Web API - How to upload excel file with request parameters using Fiddler

I am uploading excel file on server through Web Api. I need to pass some parameters along with the file.
But when I am using fiddler i can able to get either Request parameters or file only, but i need both things in my web API controller.
Method Type: Post
URL : http://localhost/MP.Services/api/catalog/file/upload/
Request Header-
User-Agent: Fiddler
Host: localhost
Content-Length: 74
Content-Type: application/json; charset=utf
Request Body-
{
"CatalogCode":"1",
"Action":"1",
"Entity":"1",
"UploadedBy":"1"
}
Above is my Normal way to pass request parameter, I tried to upload the excel file in fiddler from 'Upload file' option along with above request, but when file gets uploaded request header and request body gets change.
When I run this then I will not able to get the Request Parameters to my web API controller.
My Controller Action Code-
[HttpPost]
public async Task<HttpResponseMessage> UploadCatalogExcel(CatalogUploadRequest catalogUploadRequest)
{
if (catalogUploadRequest == null)
return CreateResponse(HttpStatusCode.NotAcceptable, ControllerErrorCodeConstants.RequestIsInvalid, "Invalid request");
if (!ModelState.IsValid) return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
if (!Request.Content.IsMimeMultipartContent())
return Request.CreateResponse(HttpStatusCode.UnsupportedMediaType, "Uploading file is mandatory");
try
{
//Request to BL Mapping
var catalogUploadExcelBi = CatalogUploadMapping.UploadCatalogExcelRequestToBiMap(catalogUploadRequest);
var CatalogInfo = _catalogUploadBi.GetSampleCatalogExcel(catalogUploadExcelBi.CatalogCode);
string uploadPath = HttpContext.Current.Server.MapPath("~/App_Data");
uploadPath = uploadPath + "\\Upload\\" + CatalogInfo.SellerAccountId + "_" + CatalogInfo.SellerAccountName + "\\" + DateTime.Now.Year.ToString() + "_" + CatalogInfo.CatalogCode; // Physical File Location
string currentTime = Regex.Replace(DateTime.Now.ToString(), "[^0-9]+", "");
string name = catalogUploadExcelBi.CatalogCode + "_" + currentTime + ".xlsx"; // File Name
catalogUploadExcelBi.FileName = "aa";
catalogUploadExcelBi.FilePath = uploadPath;
bool exists = System.IO.Directory.Exists(uploadPath);
if (!exists)
System.IO.Directory.CreateDirectory(uploadPath);
MyStreamProvider streamProvider = new MyStreamProvider(uploadPath);
await Request.Content.ReadAsMultipartAsync(streamProvider);
var response = _catalogUploadBi.LogUploadCatalogExcel(catalogUploadExcelBi);
if (response.ServerErrors != null && response.ServerErrors.Count != 0)
{
response.ServerErrors = response.ServerErrors;
return Request.CreateResponse(HttpStatusCode.BadRequest, response.ServerErrors);
}
return Request.CreateResponse(HttpStatusCode.OK, "File uploaded successfully");
}
catch (Exception ex)
{
var error = _errorManager.GetCustomeError(ex.GetType().ToString());
return error != null && !string.IsNullOrWhiteSpace(error.ErrorCode) && !string.IsNullOrWhiteSpace(error.ErrorMessage)
? Request.CreateResponse(string.Format("Exception Occured! Error code : {0} Error Message : {1}", error.ErrorCode,
error.ErrorMessage)) : Request.CreateResponse(string.Format("Upload file method Exception Occured!"));
}
}

Google Batch permissions request return success but no permission granted for users

I have to create multiple user permissions for a single folder by using Drive REST API. If I do requests (more than one) continuously for each user (because Document List API batchACL deprecated) It returns permissionIds for every user but most of the time only one user granted the permission. This caused errors in my application. I moved to Google Batch Requests and my request postBody is generated like this,
var postBody = "";
dataObj.users.forEach(function (entry) {
var batchBody = {role: entry.role, type: "user", value: entry.email };
batchBody = JSON.stringify(batchBody);
postBody = postBody.concat("--batch_", collectionId, "\n");
postBody = postBody.concat("Content-Type: application/http \n");
postBody = postBody.concat("Content-ID: ", entry.email, "\n");
postBody = postBody.concat("Content-Transfer-Encoding: binary \n");
postBody = postBody.concat("POST /drive/v2/files/", collectionId, "/permissions \n");
postBody = postBody.concat("Content-Type: application/json \n");
postBody = postBody.concat("Content-Length: ", batchBody.length, " \n");
postBody = postBody.concat(batchBody, " \n");
});
postBody = postBody.concat("--batch_", collectionId, "--");
it returns success with 200 and response body is like this,
--batch_vfFEpoYZl9Q_AAYPEVhdVNI--
--batch_vfFEpoYZl9Q_AAYPEVhdVNI--
but no permission granted for any user. And the response body shouldn't like this as per the Google documentation. Can someone help me to find the problem or any guidance to use "google-api-nodejs-client" to do the same batch request?

Resources