Google Plus Signin 'Unknown RPC service: widget-interactive-I0_1370237493291' - google-plus

Sorry for such a noob question.
I just followed following google plus signin's Step1 to Step4.
https://developers.google.com/+/web/signin/
The signin seemed to succeed, while an error 'Unknown RPC service: widget-interactive-I0_1370237493291' emerged. Here are the console logs on Chrome.
XHR finished loading: "https://plusone.google.com/_/scs/apps-static/_/js/k=oz.connect.en_US.B31L_d…sv=1/d=1/ed=1/am=GA/rs=AItRSTOhxGvE7YZFbwjOy6nLkxCnNjz3og/cb=gapi.loaded_1". signin:15
XHR finished loading: "https://plusone.google.com/_/scs/apps-static/_/js/k=oz.gapi.en.hgKKOofQjvI.…sv=1/d=1/ed=1/am=EQ/rs=AItRSTOeNwU4i5ApX9gPGjnZ0AzovKWmWw/cb=gapi.loaded_0". signin:15
Unknown RPC service: widget-interactive-I0_1370237493291 cb=gapi.loaded_0:71
signed in
I think the error is about something incomplete. I cannot figure out what the exactly the error is and how to get it clear. What am I missing?
Here is the code. The origin is http://localhost:3000
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Gplus</title>
</head>
<body>
<h1>Gplus</h1>
<span id="signinButton">
<span
class="g-signin"
data-callback="signinCallback"
data-clientid="362449793624.apps.googleusercontent.com"
data-cookiepolicy="single_host_origin"
data-requestvisibleactions="http://schemas.google.com/AddActivity"
data-scope="https://www.googleapis.com/auth/plus.login">
</span>
</span>
<script type="text/javascript">
function signinCallback(authResult) {
if (authResult['access_token']) {
// Successfully authorized
// Hide the sign-in button now that the user is authorized, for example:
document.getElementById('signinButton').setAttribute('style', 'display: none');
console.log('signed in');
} else if (authResult['error']) {
// There was an error.
// Possible error codes:
// "access_denied" - User denied access to your app
// "immediate_failed" - Could not automatically log in the user
// console.log('There was an error: ' + authResult['error']);
}
}
</script>
<!-- Place this asynchronous JavaScript just before your </body> tag -->
<script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/client:plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script>
</body>
</html>

I had the same problem when I was trying that code sample. When trying to figure it out, I found this post:
https://groups.google.com/forum/?fromgroups#!topic/google-plus-developers/Ax3cMLhMR4Q
in the Google+ Developers Forum that seems to indicate that it's not really an 'error' but some kind of warning. If I find out more, I'll post an update here.
Hope this helps.

Related

Autodesk Forge Viewer API not working in React Native

A few days ago, I was trying to build Autodesk forge viewer API with react native by following this example:
https://forge.autodesk.com/blog/forge-react-native-au-talk
It works well. It used viewer v2.17, I up to viewer v7 but unfortunately, It doesn't show anything. I caught an error: Cannot read property 'texture' of null, when I use line viewer.start();
Please, help
Looking at your code it seems to me you're not using the viewer options properly on initializing.
The way to define the access token is by a callback as per the sample posted by Bryan.
Using the code below the viewer loaded in fine.
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<link rel="stylesheet" href="https://developer.api.autodesk.com/derivativeservice/v2/viewers/style.min.css?v=v7.*" type="text/css">
<script src="https://developer.api.autodesk.com/derivativeservice/v2/viewers/three.min.js?v=v2.17"></script>
<script src="https://developer.api.autodesk.com/derivativeservice/v2/viewers/viewer3D.js?v=v7.*"></script>
</head>
<body style="margin:0">
<div id="viewer"></div>
</body>
<script>
var viewer = null;
function initializeViewer(urn, token) {
var options = {
env: "AutodeskProduction",
getAccessToken: function(onTokenReady) {
var token = 'access token provided by 2 legged api';
var timeInSeconds = 3600; // Use value provided by Forge Authentication (OAuth) API
onTokenReady(token, timeInSeconds);
}
}
Autodesk.Viewing.Initializer(options, () => {
try {
viewer = new Autodesk.Viewing.GuiViewer3D(document.getElementById('viewer'));
viewer.start();
console.log('viewer loaded');
} catch (err) {
alert(err)
}
});
function onDocumentLoadSuccess(doc) {
var viewables = doc.getRoot().getDefaultGeometry();
viewer.loadDocumentNode(doc, viewables).then(i => {
// documented loaded, any action?
});
}
function onDocumentLoadFailure(viewerErrorCode) {
console.error('onDocumentLoadFailure() - errorCode:' + viewerErrorCode);
}
}
</script>

PhantomJs can't render a specific page from source

I have been successfully able to take raw html (that has been retrieved with another product) then have phantomjs take that raw html and render the full page including running any/all javascript. I recently encountered a page that was not having its javascript rendered.
This is how I run it...
phantomjs myscript.js > OUTPUT.txt 2>&1
Here is the myscript.js file that demonstrates the issue...
var page = require('webpage').create(),
var system = require('system');
var address = 'http://cloud.firebrandtech.com/#!/login';
var rawHtml = '<!DOCTYPE html>\
<html>\
<head>\
<meta charset="utf-8">\
<meta http-equiv="X-UA-Compatible" content="IE=edge">\
<meta name="viewport" content="width=device-width, initial-scale=1.0">\
<meta name="description" content="Web Portal for managing Cloud Products, Assets, and Distributions">\
<meta name="author" content="Firebrand Technologies">\
<title>Firebrand Cloud</title>\
<link rel="stylesheet" href="/widgets/css/widgets.css">\
<link rel="stylesheet" href="/css/portal.css">\
</head>\
<body ng-app="portal" fc-app="cloud" fc-direct="true" class="fc">\
<div>\
<div data-ng-if="user.isLoaded" data-ng-controller="PortalCtrl">\
<div data-ng-include="getView()"></div>\
<div class="container">\
<div data-ui-view></div>\
</div>\
</div>\
</div>\
<script src="/widgets/js/widgets.js"></script>\
<script src="/js/vendor.js"></script>\
<script src="/js/portal.js"></script>\
</body>\
</html>';
page.settings.resourceTimeout = 5000;
page.settings.loadImages = false;
page.setContent(rawHtml, address);
window.setTimeout(function () {
if(page.content.indexOf('Sign In') > -1)
console.log('YAY!!! Javascript Rendered!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
else
console.log('BOO!!! Javascript NOT Rendered!!!!!!!!!!!!!!!!!!!!!!!!!!')
phantom.exit();
}, 5000);
Seems like this page requires some auth/cors to work. I can get it to work if phantomjs makes the actual request (using page.open) to get the source like the following example. However, this solution will not work for me. Phantomjs has to use the source like in the example above (which like I mentioned, has been working great for all other sites).
var page = require('webpage').create(),
var system = require('system');
var address = 'http://cloud.firebrandtech.com/#!/login ';
page.open(address, function(status) {
setTimeout(function(){
if(page.content.indexOf('Sign In') > -1)
console.log('YAY!!! Javascript Rendered!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
else
console.log('BOO!!! Javascript NOT Rendered!!!!!!!!!!!!!!!!!!!!!!!!!!')
phantom.exit();
}, 5000)
});
I have already tried using flags like the following but they seem to have no effect...
phantomjs --web-security=false --ignore-ssl-errors=true thefilebelow.js > OUTPUT.txt 2>&1
Finally got this working...
Since I used another product (not phantomjs) to retrieve the page source, I needed to persist the cookies sent back with that request. Then I had to pass in those cookies using addCookie like so...
var page = require('webpage').create(),
var system = require('system');
var address = 'http://cloud.firebrandtech.com/#!/login';
var rawHtml = 'same raw html as above...';
//THE NEXT 3 LINES ARE WHAT CHANGED
var cookiesFromInitialRequest = [{name: 'aaa', value: 'bbb', domain: 'ccc'}, etc...]
for(var i = 0; i < cookiesFromInitialRequest.length; i++)
phantom.addCookie(cookiesFromInitialRequest[i])
page.settings.resourceTimeout = 5000;
page.settings.loadImages = false;
page.setContent(rawHtml, address);
window.setTimeout(function () {
if(page.content.indexOf('Sign In') > -1)
console.log('YAY!!! Javascript Rendered!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
else
console.log('BOO!!! Javascript NOT Rendered!!!!!!!!!!!!!!!!!!!!!!!!!!')
phantom.exit();
}, 5000);

Google SignIn State

I'm trying to build a Google signin button into my website. I'm trying to avoid using their built-in button. The code below works to sign in a user, but I can't figure out how to make my webpage remember that they're signed in when the user refreshes the page, or leaves the site and comes back.
Using Chrome's developer tools, I can see that there's an entry for https://accounts.google.com under both Local Storage and Session Storage. They seem to more or less contain the same information, including the user's validated token.
What I don't understand is how to get the gapi.auth2.init() function to recognize and use this token. The documentation doesn't seem to cover it.
<html>
<head>
<title>Login Test</title>
<script src="http://code.jquery.com/jquery-2.1.4.js"></script>
<script src="https://apis.google.com/js/platform.js?onload=renderButton" async defer></script>
</head>
<script>
var googleUser = {};
function renderButton() {
gapi.load('auth2', function(){
auth2 = gapi.auth2.init({
client_id: 'MY_CREDENTIALS.apps.googleusercontent.com',
});
attachSignin(document.getElementById('customBtn'));
});
};
function attachSignin(element) {
auth2.attachClickHandler(element, {},
function(googleUser) {
document.getElementById('name').innerText = "Signed in: " +
googleUser.getBasicProfile().getName();
}, function(error) {
alert(JSON.stringify(error, undefined, 2));
}
);
}
</script>
<body>
<div id="gSignInWrapper">
<span class="label">Sign in with:</span>
<input type="button" id="customBtn" value="Google"></input>
</div>
<p id="name"></p>
</body>
</html>
You can use listeners. This is the relevant part:
// Listen for sign-in state changes.
auth2.isSignedIn.listen(signinChanged);
// Listen for changes to current user.
auth2.currentUser.listen(userChanged);
You can also get up to date values by
var isSignedIn = auth2.isSignedIn.get();
var currentUser = auth2.currentUser.get();
To strictly detect returning users only you can do:
var auth2 = gapi.auth2.init(CONFIG);
auth2.then(function() {
// at this point initial authentication is done.
var currentUser = auth2.currentUser.get();
});
When it comes to your code I would do:
auth2 = gapi.auth2.init(CONFIG);
auth2.currentUser.listen(onUserChange);
auth2.attachClickHandler(element, {});
This way all changes in sign-in state are passed to onUserChange (this includes returning users, new sign-ins from attachClickHandler, new sign-ins from different tab).

Google-plus sign in: the code runs twice, user was logged out right after he logs in

this is a page built on example
<html>
<head>
<title>Demo: Getting an email address using the Google+ Sign-in button</title>
<style type="text/css">
html, body { margin: 0; padding: 0; }
.hide { display: none;}
.show { display: block;}
</style>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js" ></script>
<!--<script src="https://apis.google.com/js/plusone.js" type="text/javascript"></script>-->
<script src="https://apis.google.com/js/client:plusone.js" type="text/javascript"></script>
<script type="text/javascript">
/*
* Triggered when the user accepts the sign in, cancels, or closes the
* authorization dialog.
*/
function loginFinishedCallback(authResult) {
if (authResult) {
console.log('authResult : ',authResult);
if (authResult['error'] == undefined){
gapi.auth.setToken(authResult); // Store the returned token.
toggleElement('signin-button'); // Hide the sign-in button after successfully signing in the user.
getEmail(); // Trigger request to get the email address.
} else {
console.log('An error occurred');
}
} else {
console.log('Empty authResult'); // Something went wrong
}
}
/*
* Initiates the request to the userinfo endpoint to get the user's email
* address. This function relies on the gapi.auth.setToken containing a valid
* OAuth access token.
*
* When the request completes, the getEmailCallback is triggered and passed
* the result of the request.
*/
function getEmail(){
// Load the oauth2 libraries to enable the userinfo methods.
gapi.client.load('oauth2', 'v2', function() {
var request = gapi.client.oauth2.userinfo.get();
request.execute(getEmailCallback);
});
}
function getEmailCallback(obj){
var el = document.getElementById('email');
var email = '';
console.log("OBJ = ",obj)
if (obj['email']) {
email = 'Email: ' + obj['email'];
}
//console.log(obj); // Uncomment to inspect the full object.
el.innerHTML = email;
toggleElement('email');
}
function toggleElement(id) {
var el = document.getElementById(id);
if (el.getAttribute('class') == 'hide') {
el.setAttribute('class', 'show');
} else {
el.setAttribute('class', 'hide');
}
}
</script>
</head>
<body>
<div id="signin-button" class="show">
<div class="g-signin" data-callback="loginFinishedCallback"
data-approvalprompt="auto"
data-clientId="751931329576.apps.googleusercontent.com"
data-scope="https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/userinfo.email"
data-height="short"
data-cookiepolicy="http://semicon-equip.com"
>
</div>
<!-- In most cases, you don't want to use approvalprompt=force. Specified
here to facilitate the demo.-->
</div>
<div id="email" class="hide"></div>
</body>
</html>
Question 1: It always fails with "Uncaught TypeError: Cannot read property 'load' of undefined",
until I use
<script src="https://apis.google.com/js/client:plusone.js" type="text/javascript"></script>
instead of the example code:
<script src="https://apis.google.com/js/plusone.js" type="text/javascript"></script>
What's the difference between plusone.js and client:plusone.js ?
Question 2: Why the code run twice per page loads ?
Qestion 3: the user was logged out after he just signed in, how to fix ?
error demo page for the above (all the errors are in the background console).
This is not really an answer to the question, but a step by step procedure to reproduce it.
Below the simple html page I'm using to test (similar to the example from Ray C Lin).
I've made it as simple as possible to avoid interactions with other part of the code :
<html>
<head>
<script type="text/javascript"
src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
</head>
<body>
<input type="button" id="signOut" value="Sign out"></button>
<span id="signinButton">
<span class="g-signin"
data-accesstype="offline"
data-callback="signinCallback"
data-clientid="YOUR_CLIENT_ID_HERE"
data-cookiepolicy="single_host_origin"
data-scope="email"
</span>
</span>
<script type="text/javascript">
$('#signOut').on('click', function() {
gapi.auth.signOut();
});
function signinCallback(authResult) {
console.log("signinCallback: ", authResult);
}
(function() {
var po = document.createElement('script');
po.type = 'text/javascript';
po.async = true;
po.src = 'https://apis.google.com/js/client:plusone.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(po, s);
})();
</script>
</body>
</html>
You will have to update data-clientid with your own google client id, and display this page from an authorized javascript origin.
Please note that this might not work from localhost, as Ian suggested in a comment to this post https://plus.google.com/102746521318753162868/posts/Z5Gkro9YXVs
First, sign in using your Google account : you will see a successful callback in the console.
If you click on Sign out, you will see a callback with 'user_signed_out' in the console.
So far so good.
Sign-in again, and wait 1 hour, until the token expires (this is awful to test, as I don't know how to reduced the token lifetime).
After one hour, click on the sign out button : no callback is called.
Click on the sign-in button again :
you get a successfull callback with an authorization code and access token
immediately after, you get a 'user_signed_out' callback.
Once a session has expired, there is no way to return to a "normal" situation, you always get this second callback with 'user_signed_out'.
Actually, there is one way to return to a "normal" situation: revoke the access to the app from the google dashboard.
This is not really an issue for me as I'm using Google+ only to sign-in the user to my app using the one time authorization code, and I'm not using the access token from the client.
But this prevent automatic login from working, as the user is immediately considered as "signed out" from a google perspective.
Q1: client:plusone.js is just telling the loader to automatically load the "client" module. It's basically automatically doing gapi.load("client"), except it is already packaged up for you in one download. You could do it the other way around as well, plusone:client.js!
Q2: Not sure, it may be some JS quirk. In general, try and make your code able to handle multiple callbacks, you may get another if the state changes (e.g. the user logs out of their google account).
Q3: I don't see that on the test page - I am signed OK, and still signed in on refresh! Check you're not blocking third party cookies in your browser or similar?

Googleplus API emails list is undefined

According to the googleplus documentation the there are many fields for the user, one example is emails. But when I make a https://www.googleapis.com/plus/v1/people/me?key=, i don't get back the emails i have defined in my contact section under emails. I tried making them public as well, still no luck.
A couple things:
There is a known issue where the email list will not be returned
You can request an additional scope, userinfo.email to get a user's verified email address
The following example shows how this can be done in JavaScript:
<html>
<script type="text/javascript">
function onSigninCallback(resp){
console.log(resp);
gapi.client.load("oauth2", "v2", function(){
gapi.client.oauth2.tokeninfo(
{'access_token' : resp.access_token}).
execute(function(innerResp){console.log(innerResp.email);});
});
}
</script>
<body>
<span class="g-signin"
data-scope="https://www.googleapis.com/auth/userinfo.email"
data-requestvisibleactions="http://schemas.google.com/AddActivity"
data-clientId="YOUR_CLIENT_ID"
data-callback="onSigninCallback"
data-theme="dark"
data-cookiepolicy="single_host_origin">
</span>
</body>
<script>
/**
* Load the Google+ JavaScript client libraries.
*/
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/auth:plusone.js?onload=startApp';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script>
</html>
An open issue, "ability to obtain an emails list" exists in the Google+ Platform Issue tracker, feel free to star the issue or add a comment.