GoogleFit.authorize not responding/working - google-fit

In my one of React Native app, there is a feature to connect with Google Fit. When user tapps on connects Google Fit, it prompts for device accounts to choose the account and then nothing happens, no error event receives also. I can't understand whats the issue.
Although this is working fine in debug and release build. When we upload the app to Google Play, and user downloads the app from play store, then only problem occurs.
Can anyone please help me?
const options = {
scopes: [
Scopes.FITNESS_ACTIVITY_READ,
Scopes.FITNESS_BODY_READ,
Scopes.FITNESS_HEART_RATE_READ,
Scopes.FITNESS_BLOOD_PRESSURE_READ,
Scopes.FITNESS_SLEEP_READ,
],
}
GoogleFit.authorize(options)
.then(async authResult => {
console.log(JSON.stringify(authResult));
if (authResult.success) {
dispatch(actionCreator.getActionObject('UPDATE_isGooglefitLoggedIn', true));
}
})
.catch((error) => {
alert("AUTH_ERROR", JSON.stringify(error));
})

Given the users cannot signin using their Google account, make sure you configured the right SHA release certificate in the GCP project. When you release your App in Play Store, the signature of the binary signed by the upload key certificate will be different than the binary distributed by Google Play. You can find the Play App Signing page under Release > Setup > App Integrity and update your GCP OAuth client accordingly.

Related

Application Default Credentials Not Working in Cloud Function to access Google Workspace API

I am trying to use the service account using Google Cloud Functions to access the Workspace Directory API. I am trying to use Application Default Credentials approach. Since the documentation doesn't mention any additional steps to be done in the Google Cloud Console side, I assume that Application Default Credentials (ADC) to the function is automatically passed to the cloud function from Google Cloud's Metadata server. The following code works perfectly in my local, emulated environment where I have set GOOGLE_APPLICATION_CREDENTIALS environment variable to point to the JSON credential file. However when I deploy the function to Google Cloud, I am getting the error "Not Authorized to access this resource/api". I have been searching and trying for days without any success. As an aside, before I stumbled upon this thread, I was using getCredentials() method of GoogleAuth to get the private_key to create JWT auth (for the "subject" property) and passing that auth to admin API call. Which again worked perfectly in my local environment but fails in the cloud environment because getCredentials() private_key is null, which is probably expected behavior. Any help is deeply appreciated. I am inexperienced with posting in Stackoverflow, if I need to follow any other protocol, please advise.
export const listUsers = functions.https.onCall((data, context) => {
return new Promise(async (resolve, reject) => {
const envAuth = new GoogleAuth({
scopes: ["https://www.googleapis.com/auth/admin.directory.user.readonly"],
clientOptions: {
subject: "admin#mydomain.com",
},
});
const client = await envAuth.getClient();
const service = google.admin({version: "directory_v1", auth: client});
try {
const response = await service.users.list({
customer: "MYCUSTOMER_ID",
});
resolve(response);
} catch (err) {
reject(err);
}
});
});
When you run a Cloud Function without authenticating via a key file (the json credential file that has the key to allow you to impersonate/authenticate as a different user), the function runs as the default application credentials for the project (<YOUR_CLOUD_PROJECT_ID>#appspot.gserviceaccount.com). You don't have to do anything special, no authentication calls -- it runs with the permissions of this service account by default.
When you run the code locally, it takes on the user authentication of whatever key file you have locally (and have referenced in the "GOOGLE_APPLICATION_CREDENTIALS" environment variable on your machine).
Without full security information on your environment, it's hard to know for sure... But, I'm guessing that you're trying to access resources that your personal Google Account has proper access; however, the default service account for you Cloud Functions Project does not.
So, couple of routes to troubleshoot and/or fix the issue:
Give the default service account access rights to Workspace resource(s) you're attempting to access.
Use the JSON key file you setup locally already, to have the Cloud Function run as the same user as is happening when you run locally.
Essentially do a hybrid where you create a new service account that ONLY has the permissions you want (instead of using the default service account or your personal user, both of which might have far more permissions then desired for safety/security), use a key file to run the Cloud Function under that identity, and only give the desired permissions to that service account.

gapi.auth.authorize() with immediate: false doesn't popup a window for authorization

Below is a javascript which simply requests authorization to access user's spreadsheets:
var CLIENT_ID = '********';
var SCOPES = [
'https://www.googleapis.com/auth/spreadsheets'
];
function auth() {
gapi.auth.authorize({
client_id: CLIENT_ID,
immediate: true,
scope: SCOPES
}, function(result) {
console.log('authorize(immediate = true)');
if (result && !result.error) {
console.log('authorize [OK]');
} else {
console.log('authorize [FAILED]');
gapi.auth.authorize({
client_id: CLIENT_ID,
immediate: false,
scope: SCOPES
}, function(result) {
console.log('authorize(immediate = false)');
if (result && !result.error) {
console.log('authorize [OK]');
} else {
console.log('authorize [FAILED]');
}
});
}
});
}
I believe it should do two things:
Popup a window to login unless the user is already logged in.
Popup a window to request authorization to access user's spreadsheets unless the authorization had been already granted earlier. After the authorization is granted the app should be listed under Connected apps & sites and no more popup with authorization will be shown.
I am testing this script with two distinct google accounts. One account works as expected and I get the following output on console:
auth.html:17 authorize(immediate = true)
auth.html:21 authorize [FAILED]
auth.html:27 authorize(immediate = false)
auth.html:29 authorize [OK]
With another account the popup for authorization is not shown and authorization is always granted as If I pressed "Allow" or the app was listed under Connected apps & sites, but it's not there. The console output is exactly the same.
I have done these tests using two browsers:
Version 51.0.2704.79 Built on 8.4, running on Debian 8.5 (64-bit)
Firefox ESR 45.2.0, running on Debian 8.5 (64-bit)
So, basically I have the following questions:
Are my expectations regarding popups correct or the idea behind the gapi.auth.authorize() call with immediate:true or immediate:false is different?
What can be the reason for this "misbehaving"? Is there any "sacred place" where the app is listed as authorized for some scope while the same app not shown under Connected apps & sites?
Note: The CLIENT_ID is listed in Google API Console under OAuth
2.0 client IDs, the type is Web application and the owner is completely different account not related to the above mentioned two.
Thanks.
To answer your questions:
Are my expectations regarding popups correct or the idea behind the gapi.auth.authorize() call with immediate:true or immediate:false is different?
Yes, your expectations regarding popups are correct. As discussed in a related issue #103 posted in GitHub, when user triggers 'gapi.auth.authorize' with button click (immediate:false), flow is as following:
Popup window with permissions authorization is shown
When user accept/deny, popup window is closed
instead of firing callback, TypeError appears in console (regardless of whether user authorized app to handle requested data or not)
What can be the reason for this "misbehaving"? Is there any "sacred place" where the app is listed as authorized for some scope while the same app not shown under Connected apps & sites?
That related issue #103 posted in GitHub can also be the reason for this "misbehaving" and based from the thread, this has already been fixed which can be found in that GitHub post.
I hope that helps.

Google Chrome GCM registration doesn't work

I have problem with GCM registration in Google Chrome. I've created minimal example:
manifest.json
{
"name": "TestGCM",
"version": "0.1",
"description": "Desc.",
"permissions": ["gcm"],
"background": {
"scripts": ["background.js"],
"persistent": true
},
"manifest_version": 2
}
background.js
var gcmSenderId = "782709818071";
var registerGcm = function(gcmRegistrationId) {
console.log("registerGcm start");
var lastError = chrome.runtime.lastError;
if (lastError) {
console.error("Error during registering GCM token: ", lastError.message);
}
console.log("registerGcm end");
};
var senderIds = [gcmSenderId];
console.log("registering GCM...");
chrome.gcm.register(senderIds, registerGcm);
console.log("...");
var lastError = chrome.runtime.lastError;
if (lastError) {
console.error("Error: ", lastError.message);
}
After I load this extension I only see:
registering GCM...
...
Registration doesn't work. I tried resetting Google Chrome settings to factory, reinstalling Chrome, restarting PC.
In chrome://gcm-internals/ I see that GCM client state is UNINITIALIZED:
Android Id
User Profile Service Created true
GCM Enabled true
GCM Client Created true
GCM Client State UNINITIALIZED
Connection Client Created false
Connection State
Registered App Ids
Send Message Queue Size 0
Resend Message Queue Size 0
There is a chance that you are dealing with corrupted GCM store. If this is a signed-in (see below) profile, and GCM Client is still shown as UNINITIALIZED, that would be the case. A way to deal with that is to go a corresponding profile's folder and delete the GCM Store folder. Restarting Chrome should reinitialize GCM for the signed in profile, and your application should be able to work.
My only concern about that solution is that you mentioned that you reinstalled Chrome, which I would expect to delete the folders and this solution would not address the problem. On an off chance that you are using the old profile and it happens to be corrupted, please try these steps.
GCM Client in desktop Chrome is built in a way, that you don't need to be signed-in to have GCM running, it is enough to have an app/extension using GCM, but signing in and enabling Chrome Sync is an easy way to test that GCM works properly. That is the only reason I am recommending it.
Check this documentation about Implementing GCM Client on Chrome, to know the basic steps you need to obtain GCM registration token.
It's explained here the steps and key points that you need to register the GCM. It has a sample code that you can use or serve as a guide for your project.
Also make sure that the enable API that you use is "Google Cloud Messaging for Android". Because "Google Cloud Messaging for Android" will give you access to the normal GCM API. "Google Cloud Messaging for Chrome" won’t (it’s used for Chrome Apps in the Chrome Web Store).
Also check this tutorial on how to use Google Cloud Messaging in Chrome.

How do I configure project and gcloud to connect to Datastore?

I'm unable to get my Google Compute instance to speak to the Datastore (within the same project).
I believe I've set everything up correctly:
Google Compute instance has the full API scope
All the relevant APIs have been enabled in the project
Billing is enabled in the project
The tutorials claim that I won't even need to have a service account to use the API, but since it didn't work I also tried setting up a service account and put the key file on my instance. Still no luck.
Here's the code I'm trying to run (I created a Test entity in the Datastore of the project, and I can successfully look it up using Google's API explorer with an OAuth2 token for my account):
const gcloud = require('gcloud')({
projectId: 'roger-web-client',
keyFilename: './roger-web-client-8d1fbd8baae2.json',
});
const dataset = gcloud.datastore.dataset();
dataset.get(dataset.key(['Test', 5629499534213120]), (error, entity) => {
console.log(error || entity);
});
This results in the error 403 Forbidden. If I comment out keyFilename, I get 401 Unauthorized instead, which seems to imply the magic authorization on Google Compute instances isn't working for me.
Ideas?

Google user login when testing local app

I'm working on an app that consumes the Google Drive API. Google's documentation states two conditions necessary for authentication to be successful:
The user is signed-in to their Google account.
The user has granted permission to your app to access their data within the requested scopes.
How can I allow the user to sign in when testing locally?
My app is currently built with the Jekyll framework, which serves locally to 127.0.0.1:4000.
I found the answer in some additional documentation.
In the following function, changing immediate from true to false forces the app to ask for authentication. Otherwise, authentication silently fails if the user isn't logged in.
function handleAuthClick(event) {
gapi.auth.authorize({client_id: clientId, scope: scopes, immediate: true}, handleAuthResult);
return false;
}