I am new to the Google api and I am working on an app to allow us to stream a video to a user's youtube account. I'm having a hard time determining how to configure the login process to handle that. I used the sample code from the SDK and the login window opens fine. But I can't determine what is the scope and discovery docs to pass in the enable the Live Streaming API. Any help would be greatly appreciated.
Edited to add: I found the code snippet below and it now loads the window prompting me to give permission. But when I click to allow the app access it returns calls the error function with the message "popup_closed_by_user"
gapi.auth2.getAuthInstance()
.signIn({scope: "https://www.googleapis.com/auth/youtube"})
.then(function() {
try {
console.log("Sign-in successful");
gapi.client.setApiKey(global.google_stream_apiid);
var tmp2 = gapi.client.load("https://www.googleapis.com/discovery/v1/apis/youtube/v3/rest")
.then(function() {
console.log("GAPI client loaded for API");
},
function(err) {
console.error("Error loading GAPI client for API", err);
});
console.log(tmp2)
}
catch(e){
Ext.ux.Error.handleError(e);
}
},
function(err) {
debugger;
console.error("Error signing in", err);
});
Related
I am having issue in BuildFire that works on my local computer but fails in production when the plugin is uploaded.
In my plug-in, I am having the user enter and save values to the buildfire local storage as such in my Content.js:
function saveCredentionals (){
buildfire.localStorage.setItem("bw_organizer_id", organizer_id, (error) => {
if (error) return console.error("something went wrong!", error);
console.log("All is well, data saved and other plugins can now access it");
});
buildfire.localStorage.setItem("bw_access_token", access_token, (error) => {
if (error) return console.error("something went wrong!", error);
console.log("All is well, data saved and other plugins can now access it");
});
}
The files save correctly and values can be retrieved in the Content.js, even when page reloads. Next I try to retrieve the values in Widget.js as such:
Promise.all([
buildfire.localStorage.getItem("bw_organizer_id"),
buildfire.localStorage.getItem("bw_access_token"),
]).then(items => {
let has_organizer_token = false;
let has_access_token = false;
if (items[0]) {
has_organizer_token = true;
}
if (items[1]) {
has_access_token = true;
}
if (has_access_token && has_access_token) {
displayVideoPage(items[0], items[1]);
} else {
setMainContent(<div>Organizer ID and access token required.</div>);
}
});
This works on my local computer but fails to retrieve the value when I publish my plugin and run it on the app.buildfire.com . The items from the Promise are both null on production in my Widget.js.
Any thoughts on why this is happenings? The code is also open sourced here: https://github.com/BingeWave-Libraries/buildfire-livestream
localStorage is not meant to be shared between Control and Widget as the Widget should be able to run anywhere isolated from Control.
If you're looking to use localStorage as a shared communication you can check
BuildFire Messaging
If you're looking to persist and share data you should look at:
BuildFire Datastore (readonly for Widget)
BuildFire Public Data (read and write for Widget)
BuildFire App Data (read and write for all app Widgets)
I'm using the Firebase Javascript SDK to add web push notifications to a React JS app. Through some sequence of events, we've wound up with two FCM tokens that appear to be from the same web client (same machine, browser and site domain). An FCM message sent to either token is received on the client. I would have expected one of the tokens to get invalidated, but that doesn't seem to be the case. Is it possible to identify and delete the extraneous token when this situation occurs?
The code to register our service worker and send the FCM token to our backend service looks like this:
firebase.initializeApp(Config.firebase);
this.messaging = firebase.messaging();
this.setupNotifications(this.messaging, this.loadAlerts.bind(this));
setupNotifications(messaging, handler) {
let _this = this;
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('./sw/firebase-messaging-sw.js')
.then(function(registration) {
registration.update();
_this.messaging.useServiceWorker(registration);
Notification.requestPermission().then(messaging.requestPermission)
.then(function (t) {
return messaging.getToken();
})
.then(function (token) {
// This saves the token to our server
Service.register(token);
})
.catch(function (error) {
console.log('Error occured: ' + error.message)
});
}).catch(e => {
console.log('Error during firebase registration: ' + e.message);
});
navigator.serviceWorker.addEventListener('message', event => {
if (event.data.incidents) {
// If the event data contains an incidents property, then this is a message from our
// service worker notification click handlers. Load details for the incidents.
window.location = some_url_path + event.data.incidents;
}
});
_this.messaging.onMessage(function (payload) {
handler();
});
_this.messaging.onTokenRefresh(function() {
messaging.getToken()
.then(function(refreshedToken) {
// This saves the refreshed token to our server
Service.register(refreshedToken);
})
.catch(function(err) {
console.log('Unable to retrieve refreshed token ', err);
});
});
}
}
A few (possibly) relevant points:
The web client had an active FCM token for some time (weeks). The new token was generated at some point, but now messaging.getToken() is returning the previous token.
Around the time the second token was generated, we had (mistakenly) changed the path to the service worker script that we pass to navigator.serviceWorker.register(). This appears to have resulted in two registered service workers (as seen in Chrome Developer Tools), but unregistering the worker with incorrect path had no effect.
Also around the same time we updated from the Firebase library we were using from 3.9.0 to 4.6.2
Through Chrome Developer tools, I can see there are two IndexedDBs, and one of them has an fcm_token_object_Store with the extraneous token, which is different than the token returned by messaging.getToken() displayed in the console output in the image below:
However it happened that these two FCM tokens got created, what my primary concern is how to get rid of one of them. Is there some way to get all active FCM tokens for a client instance so we could call messaging.deleteToken() on the extraneous one? It was only by fluke I was able to identify the two tokens in question on a machine I could debug on, so if this happens for a real end-user, I'm not sure how we'd correct the situation.
I'm developing an application with Cordova and would like to save files in Googe Drive.
I've got success in login to Google, using the cordova-plugin-googleplus (https://github.com/EddyVerbruggen/cordova-plugin-googleplus). However I could not get the plugin returns to me accessToken or idToken so I could use with Google javascript API.
window.plugins.googleplus.login(
{
'scopes': 'https://www.googleapis.com/auth/drive.file profile',
'offline': true,
'webApiKey': ‘CODE’
},
function (obj) {
$scope.$apply(function() {
$scope.srcImage = obj.imageUrl;
$scope.NomeGoogle = obj.displayName;
});
},
function (msg) {
alert('Erro');
alert('error: ' + msg);
}
);
I tried using the code below, but returned me the following error:
"Uncaught gapi.auth2.ExternallyVisibleError: Invalid cookiePolicy"
gapi.load('auth2', function() {
gapi.auth2.init({
client_id: 'REVERSED_CLIENTID',
}).then(function(){
auth2 = gapi.auth2.getAuthInstance();
console.log(auth2.isSignedIn.get()); //now this always returns correctly
});
});
I managed to figure out the problem, why wasn´t getting the serverAuthCode from plugin.
It is necessary to create 2 credentials on the Google Developers Console. The 1st must be Android, this will be for the plugin and the 2nd should be a Web App, this is necessary to achieve serverAuthCode.
The code looks like this
window.plugins.googleplus.login(
{
'scopes': 'https://www.googleapis.com/auth/drive.file profile',
'offline': true,
'webApiKey': ‘REVERSED_CODE of Web App Credential’
},
function (obj) {
$scope.$apply(function() {
$scope.srcImage = obj.imageUrl;
$scope.NomeGoogle = obj.displayName;
});
var data = $.param({
client_id: 'REVERSED_CODE of Web App Credential',
client_secret: 'SECRET_CODE of Web App Credential',
grant_type: 'authorization_code',
code: obj.serverAuthCode
});
var config = {
headers : {
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8;'
}
}
$http.post("https://www.googleapis.com/oauth2/v3/token", data, config).success(function(data, status) {
//data.access_token;
/** from now you can do use of google API **/
})
.error(function(data, status) {
console.log(data);
console.log(status);
});
},
function (msg) {
alert('Erro');
alert('error: ' + msg);
}
);
Thank you for your reply rojobo
At first I was hoping to skip the need for cordova-plugin-googleplus and just use the gapi within Cordova/PhoneGap to handle authentication with Google, but it appears the gapi client authentication may not work within cordova's file:// protocol.
The answer from #Joao sent me in the right direction, but I kept getting the Invalid cookiePolicy error when trying to use the gapi after retrieving the access_token (this was because I was ignoring step #2 listed below, and after authenticating with the plugini I was mistakenly trying to authenticate again with the gapi).
There is a step (#3 mentioned below) that was unclear to me. To authenticate with Google and then use the gapi in Cordova/PhoneGap, this worked instead...
use the cordova-plugin-googleplus to take care of the authentication and access token retrieval, do not use the gapi at all here
load the gapi client library (skip over the gapi.client.init() call and all the normal gapi authentication procedures)
Attach the access token we got from the plugin to the gapi client, and then make your gapi calls as needed
Step #3 took some digging for me to find, and meant I needed to add the access_token
gapi.client.setToken({access_token:'abc123456xyz'});
Once the access token was attached to the gapi client, I could use the gapi within Cordova/Phonegap:
// Load the YouTube API.
gapi.client.load('youtube', 'v3', function() {
// Do stuff...
};
try
window.plugins.googleplus.login(
{
'scopes': 'https://www.googleapis.com/auth/drive.file profile',
'offline': true,
'cookiepolicy': 'none',
'webApiKey': ‘CODE’
}
I have an Azure Mobile Services table in which the read permission is set to "Only Authenticated Users".
I followed the example here https://azure.microsoft.com/en-us/documentation/articles/mobile-services-html-get-started-users/ and am authenticating users using the following code:
function logIn() {
client.login("microsoftaccount").done(function (results) {
console.log(results);
//save auth data to local storage
sessionStorage.loggedInUser = JSON.stringify(client.currentUser);
//route to the next page based on the type of user that is logged in
getUserByUserID();
}, function (err) {
alert("Error: " + err);
});
}
I store the client.currentUser information in sessionStorage on the local machine once the user is authenticated. I then navigate to another web page where I create a new instance of the MobileServiceClient and update the client variable's currentUser variable from the sessionStorage mentioned previously. I use the following code to do that:
//load the session data into the client object
if (sessionStorage.loggedInUser) {
client.currentUser = JSON.parse(sessionStorage.loggedInUser);
console.log("getting stored user: " + JSON.parse(sessionStorage.loggedInUser));
}
However, I get a "401: Unauthorized error" when trying to read from the table using the code below:
var query = client.getTable("towingProfiles").read().done(function (results) {
console.log(JSON.stringify(results));
_.each(results, function(towingProfile){
towingProfiles.add(towingProfile);
})
}, function (err) {
alert("Error: " + err);
});
I'm not sure why this isn't working, and would appreciate any help.
The problem was that I wasn't setting the correct application key when making the MobileServiceClient.
im a newbie in javascript and wanted to learn something, I've been wondering, i found this on https://developers.google.com/api-client-library/javascript/features/cors where i can use cors so i can access a google API like kissflow, i dont know if im in the right way. so here's the thing, im using the standalone Auth client that was described in the said site, but everytime i tried to run the program the error prompt
Uncaught ReferenceError: init is not defined
i just copied the code at the site which is
<script src="https://apis.google.com/js/api.js"
type="text/javascript">
</script>`<script type="text/javascript">`
//<![CDATA[gapi.load('auth', init);//]]>
</script>
Try this:
<script src="https://apis.google.com/js/api.js"
type="text/javascript">
</script>
<script>
gapi.load("client:auth2", function() {
gapi.auth2.init({client_id: "<YOUR_CLIENT_ID>"});
});
</script>
Make sure that you host this locally, and when creating the client ID, add the localhost URL with the port. Without a URL, the client ID will not send back a proper response, resulting in an error. Since the client ID doesn't support "file:///", you have to use a web hosting service or something, or the easier route, just download the latest python and set up a localhost server.
Latest python download: https://www.python.org/downloads/
Setting up the server: https://developer.mozilla.org/en-US/docs/Learn/Common_questions/set_up_a_local_testing_server#running_a_simple_local_http_server
Note that sometimes you have to use "py" instead of "python" for reasons I am too lazy to research 😊.
To actually initiate the login and use the API:
<script>
function authenticate() {
return gapi.auth2.getAuthInstance().signIn({scope: ""/*Declare scopes with spaces in between, depends on API you're using*/})
.then(function() { console.log("Sign-in successful"); },
function(err) { console.error("Error signing in", err); });
}
function loadClient() {
gapi.client.setApiKey("<YOUR_API_KEY>");
return gapi.client.load(""/*Declare discovery document, depends on API you're using*/)
.then(function() { console.log("GAPI client loaded for API"); },
function(err) { console.error("Error loading GAPI client for API", err); });
}
function execute() {
return gapi.client.classroom.courses.list({}) //Used classroom courses list as an example, but use the apropriate API Fields, found in your method's "Overview" section on the API Documentation
.then(function(response) {
// Handle the results here (response.result has the parsed body).
console.log("Response", response);
},
function(err) { console.error("Execute error", err); });
}
gapi.load("client:auth2", function() {
gapi.auth2.init({client_id: "<YOUR_CLIENT_ID>"});
});
authenticate().then(loadClient).then(execute)
</script>
Note that sometimes you have to clear cache in order for this to work (I mean, worked for me), so if you have some trouble, try that.