Google Chrome GCM registration doesn't work - google-chrome

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.

Related

How to authenticate a cloud functions with the Api https://www.googleapis.com/drive/v3/changes/watch?

I am developing an application that interacts with Google Drive and will work as follows: When a user adds/modifies a file in Drive Share, my application will receive a notification and I will handle it. I did the development locally using Auth2 authentication and everything works perfectly, but this application will be hosted on a Cloud Functions and because of that I am not able to use Auth2 authentication, as user consent is required.
Due to this problem, I went to the perspective of using a Service Account, where I added it as the manager of my share drive, used it to create the function, and gave it all the necessary permissions, but when I modify a file, the my endpoint that was supposed to receive the message, just doesn't.
I did a search and saw that it's due to the service account not having access to user data, so it makes sense that no notification would be created.
Below I am attaching the code I am using to create the watcher on the drive and the authentication process by SA:
Code responsible for get credentials to authentication
SCOPES = [
"https://www.googleapis.com/auth/drive",
"https://www.googleapis.com/auth/drive.file",
"https://www.googleapis.com/auth/drive.readonly",
"https://www.googleapis.com/auth/drive.metadata.readonly"
]
credentials, project_id = google.auth.default(scopes=SCOPES)
credentials.refresh(req.Request())
Code responsible for creating the watch
drive = discovery.build("drive", "v3", credentials=credentials)
params = {
"kind": "api#channel",
"id": "id_watcher",
"type": "webhook",
"address": "address cloud functions"
}
# r = drive.changes().watch(fileId=file_id, body=params, supportsAllDrives=True, supportsTeamDrives=True).execute()
r = drive.changes().watch(pageToken=1,
body=params,
driveId=driverId,
includeCorpusRemovals=True,
includeItemsFromAllDrives=True,
includePermissionsForView=None,
includeRemoved=True,
includeTeamDriveItems=True,
pageSize=None,
restrictToMyDrive=None,
spaces=None,
supportsAllDrives=True,
# supportsTeamDrives=True,
# teamDriveId=driverId
).execute()
My question would be if there is a way to use Auth2 without the need for user consent, that is, without the step of opening the browser and allowing the generation of the token. If not, can you help me with a method that might work?
Remembering that this code will be in a cloud functions.
Thank you very much!
Two suggestions, one for the user consent scenario and one alternative for the notifications:
Domain Wide Delegation and Impersonation
If you are using Google Workspace and building the application for the organization. You can use Domain Wide Delegation if you are utilizing Service accounts. This would allow you to start the process of impersonation and avoid the consent of the users.
As suggested by the official documentation you can also apply and review the ways to grant the service account with the option to impersonate users.
Generating Notifications
Another suggestion could be utilizing Pub/Sub or push notifications to have your alerts. You would be able to utilize the Service account and your code and get the notifications and have them similar to an Audit log:
The image is a sample of a Gmail APi for watch and list.
References:
https://cloud.google.com/pubsub/docs/overview
Google Drive API - file watch does not notify (webhooks sample)

GoogleFit.authorize not responding/working

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.

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 Drive Error: Registered app required, either through authentication token or key param

Suddenly today requests from my service attempting to insert a file into Google drive via the Drive API started to receive a 400 error. The error indicates that a registered app is required, full error below. An application was already registered in my Google Cloud console, however the applications name did not match the application name that was used by my service. I renamed the services application name, however the error continues.
400 Bad Request
{
"code": 400,
"errors": [
{
"domain": "global",
"message": "Registered app required, either through authentication token or key param.",
"reason": "required"
}
],
"message": "Registered app required, either through authentication token or key param."
}
Is there something else that needs to be setup, or could this be a delay in the renaming of the service?
EDIT: I'm able to list, update and download files however I cannot insert.
This same issue just started to happen to us today - and we made no changes. I (think I) submitted a bug report to Google about this. Will keep digging..
UPDATE: I created a new project with private key and client ID/email and I get the same error with this new project as well. This appears to be some bug with Google Drive API service.
It happens today on my app too. I guess their service is having problem today

Google Drive authentication issues

I'm having an issue using Google Drive using Ruby.
I can create an OAuth2 client and start making authenticated calls.
I have to query the Google Documents List first in order to fetch a list of files, once I have the file IDs I try to query the Google Drive API like this:
GET https://www.googleapis.com/drive/v1/files/0B9N873iFyYR7MkRfeTAxxxxxxx?access_token=ya29.AHES6ZRckKZ2jZfC6risUtH9ZZxxxxxxxxx
However I'm getting this:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "appNotInstalled",
"message": "The authenticated user has not installed the app with client id xxxxx.apps.googleusercontent.com"
}
],
"code": 403,
"message": "The authenticated user has not installed the app with client id xxxxx.apps.googleusercontent.com"
}
}
This client id refers to an application I created via Google API Dashboard, not the Chrome Web Store.
Anyway I tried to setup a hosted Chrome Web App, configured (and paid) everything to allow a list of test users, but still I get the same error message although the app is installed correctly from the market (not local copy).
With the same client and credentials I'm able to call https://docs.google.com/feeds/ endpoints but not drive ones.
My scopes are rather complete: 'https://docs.google.com/feeds/,https://docs.googleusercontent.com/,https://spreadsheets.google.com/feeds/,http://gdata.youtube.com,plus.me,drive.file,userinfo.email,userinfo.profile'(don't look at the format, it gets fixed automatically afterwards) and they works well.
I'm not using the Drive UI, I just want to use server-side APIs. Thanks for any hints.
Have you set the "api_console_project_id" : "xxxxxxxxxxxxx" argument in your manifest ?
An example is provided here: manifest.json