I have a simple gapi (Google Drive) app that I want to connect to. There something strange that happening. I have the sample from the demo. https://developers.google.com/drive/web/quickstart/quickstart-js
//Nothing happens
<script src="static/javascript/libs/client.js?onload=Drive._handleClientLoad"></script>
//Works on reload but not refresh
// (reload) "successfully authorization"
// (refresh) "Uncaught TypeError: Cannot call method 'authorize' of undefined"
<script src="static/javascript/libs/client.js" onload="Drive._handleClientLoad"></script>
Javascript:
var Drive = {
_CLIENT_ID: '61183508825.apps.googleusercontent.com',
_SCOPES: 'https://www.googleapis.com/auth/drive.file',
_rootid: null,
authorised: false,
_auth: function() {
gapi.auth.authorize({
'client_id': Drive._CLIENT_ID, 'scope': Drive._SCOPES, 'immediate': true
},Drive._handleAuthResult);
},
_handleClientLoad: function() {
window.setTimeout(Drive._auth, 1);
},
_handleAuthResult: function(authResult) {
if (authResult && !authResult.error) {
// Access token has been successfully retrieved, requests can be sent to the API.
Drive._validAuth();
} else {
// No access token could be retrieved, show the button to start the authorization flow.
Drive._invalidAuth();
}
},
_invalidAuth: function(){
Drive.authorised = false;
console.log("invalid authorization");
},
_validAuth: function(){
Drive.authorised = true;
console.log("successfully authorization");
},
}
Why is this happening?
The html should be as per your first snippet. You need to figure out why "nothing happens". It might be some limitation in the Google lib that prevents it from calling into a module. Try replacing Drive._handleClientLoad with a global function that in turn calls your module. Perhaps sprinkle a few console.log's or debugger's in to see what is being executed and what isn't.
Not sure why but I can't call Drive._handleClientLoad from the ..client.js?onload= function, so creating a public one like bellow and it works.
function handleClientLoad() {
window.setTimeout(Drive._checkAuth, 1);
}
// ..client.js?onload=handleClientLoad
Related
I am building a simple chrome extension which integrates with Twitter using OAuth. I have slightly modified the Chrome OAuth Tutorial to integrate with Twitter. The extension is build in Reactjs+Flux.
When the user clicks on "Sign in with Twitter" button, an Action signin is triggered, which is declared as follows:
signin: function(){
ChromeUtils.connecttotwitter().then(alert("Step After Then"));
AppDispatcher.dispatch({actionType:TweetSmartActions.SIGN_IN,signedInTwitterUserId: response.user_id});
},
The ChromeUtils.connecttotwitter() is defined as follows:
var ChromeUtils = {
connecttotwitter: function () {
return new Promise(function(fulfill,reject){
var request = {
type : "background.twitterRequestToken",
};
alert("Before sendMessage");
chrome.runtime.sendMessage(request, function(response) {
if (response)
{
fulfill(response);
}
else
{
reject(response);
}
});
});
},
And the event listener onMessage is defined in the background.js as:
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
console.log("background.js: " + JSON.stringify(request));
var type = request.type;
if (type == "background.twitterRequestToken")
{
oauth.authorize(function(token,secret,userId,screenname){
sendResponse({success:true,userId:userId,screenName:screenname});
});
alert("Alerting before returning true");
return true;
}
When I click on the "Sign In With Twitter" button, the authentication flow does start and a new page opens. However, after I introduced the Promise, the new page does not redirect to the twitter oauth page. In fact, to debug that I have put the following alert statements in chrome_ex_oauth.js:
ChromeExOAuth.prototype.initOAuthFlow = function(callback) {
if (!this.hasToken()) {
var params = ChromeExOAuth.getQueryStringParams();
if (params['chromeexoauthcallback'] == 'true') {
var oauth_token = params['oauth_token'];
var oauth_verifier = params['oauth_verifier']
this.getAccessToken(oauth_token, oauth_verifier, callback);
} else {
var request_params = {
'url_callback_param' : 'chromeexoauthcallback'
}
this.getRequestToken(function(url) {
alert("Url after get request token " + url);
window.location.href = url;
alert(window.location.href);
}, request_params);
}
Here, the url in the first alert is the twitter oauth url but the second alert gives the Chrome extension Url -
chrome-extension://kiekipigbdldhggmlohbnhofnjhcbmem/chrome_ex_oauth.html
Why did the url not get assigned to window.location.href?
Any ideas on what might be happening?
The issue was not because I was using a Promise, but because when using Flux, the Action was being Dispatched before the response from the Promise was received and this was causing the app to hang somehow
signin: function(){
ChromeUtils.connecttotwitter().then(alert("Step After Then"));
AppDispatcher.dispatch({actionType:TweetSmartActions.SIGN_IN,signedInTwitterUserId: response.user_id});
},
In the above, the AppDispatcher.dispatch should be called in the function which is invoked on then.
I am trying to get the User's groups list with the following code:
$(document).ready(function() {
$("#fetchButton").click(function() {
console.log('fetch button');
FB.getLoginStatus(function(res){
if( res.status == "connected" ){ // check if logged in
// get user data first, which will be handled by an anonymours fucntion passed inline
FB.api('/me', function(meResponse) {
//console.log(meResponse);
UID = meResponse.id;
getGroups();
console.log(meResponse);
});
} else { // if not logged in, call login procedure
FB.login(function(){
$("#fetchButton").click();
}, {scope: 'publish_actions, publish_actions, read_stream, user_groups'});
}
});
});
});
function getGroups() {
FB.api('/me/groups', function(groupResponse) {
console.log(groupResponse);
});
}
This code used to work with some old version of FB SDK. But not now.
Any help!
read_stream and user_groups are deprecated and you are using publish_actions two times. In order to get a list of all the groups you manage, you need to use user_managed_groups now.
More information: https://developers.facebook.com/docs/apps/changelog#v2_4
I'm having a tough time getting push notifications (using the ngCordova plugin) to work. I have followed their sample code exactly as is documented on the site: http://ngcordova.com/docs/plugins/pushNotifications/
(the only difference is that I don't have a deviceready listener, instead, my code is inside the ionicPlatform.ready listener.)
Here is my code:
angular.module('myApp', ['ionic', 'ngCordova'])
.run(function($ionicPlatform, $rootScope, $state, $cordovaPush) {
$ionicPlatform.ready(function() {
var config = {
"senderID": "myID100001000"
};
$cordovaPush.register(config).then(function(result) {
alert(result);
}, function(err) {
alert(err);
})
});
$rootScope.$on('$cordovaPush:notificationReceived', function(event, notification) {
switch(notification.event) {
case 'registered':
if (notification.regid.length > 0 ) {
alert('registration ID = ' + notification.regid);
}
break;
default:
alert('An unknown GCM event has occurred');
break;
}
});
})
When my app starts I do get the "OK" alert, so I know it successfully goes through the $cordovaPush.register call. However, I was expecting to get a "registered" notification event, right after, but I never get notified.
Any help would be appreciated.
The solution is in the comments but this needs a proper answer.
First of all, the register callback always returns OK as long as you pass a senderID, but if the $cordovaPush:notificationReceived event is never called (it may take a few seconds), this ID is probably wrong.
You must use the Project Number, not the Project ID.
To get the number, go to the API Console, select the project and you'll be on the Overview page. On top of this page, you'll see something like this:
Project ID: your-project-id Project Number: 0123456789
Just copy and use the project number and everything should work.
I have suffered with this a lot and I have found out, that there are in fact two versions of the cordova push plugin currently:
https://github.com/phonegap-build/PushPlugin (deprecated)
https://github.com/phonegap/phonegap-plugin-push (new one)
Both are supported by ngCordova, but only the deprecated version is documented.
The deprecated version is $cordovaPush
and the newer one is $cordovaPushV5, and they have completely different methods.
For me the problem was that I downloaded the cordova-plugin-push and tried to implement it with the old documentation on ngCordova site.
The code is:
/*
* Non deprecated version of Push notification events
*/
function registerV5() {
$ionicLoading.show({
template: '<ion-spinner></ion-spinner>'
});
if (ionic.Platform.is('browser')) {
alert("You are running on broswer, please switch to your device. Otherwise you won't get notifications");
$ionicLoading.hide();
return;
}
/**
* Configuration doc:
* https://github.com/phonegap/phonegap-plugin-push/blob/master/docs/API.md#pushnotificationinitoptions
*/
var GCM_PROJECT_ID = 'xxxxxx';
$cordovaPushV5.initialize({
"android": {
"clearNotifications": false,
"senderID" : GCM_PROJECT_ID
}
});
$cordovaPushV5.register().then(function (deviceToken) {
console.log("Successfully registered", deviceToken);
$scope.data.deviceToken = deviceToken;
// Below code required to configure $cordovaPushV5 notifications emitter.
// Don't pass function it's not handler.
$cordovaPushV5.onNotification();
$cordovaPushV5.onError();
$ionicLoading.hide();
}, function (error) {
console.log("Failed to registered");
console.log("error object : ", error);
$ionicLoading.hide();
});
}
$rootScope.$on('$cordovaPushV5:notificationReceived', function(event, data) {
console.log("notification received");
console.log("data object: ", data);
var foreground = data.additionalData.foreground || false;
var threadID = data.additionalData.payload.threadID || '';
var group = data.additionalData.payload.group || false;
if (foreground) {
// Do something if the app is in foreground while receiving to push - handle in app push handling
console.log('Receive notification in foreground');
} else {
// Handle push messages while app is in background or not started
console.log('Receive notification in background');
// Open FB messanger app when user clicks notification UI when app is in background.
if (typeof data.additionalData.coldstart != "undefined" && data.additionalData.coldstart == false)
if (!group)
// Open FB Messenger of specific user chat window
window.open('fb-messenger://user/' + threadID, '_system', 'location=no');
else
// Open FB Messenger of specific group chat window
window.open('fb-messenger://groupthreadfbid/' + threadID, '_system', 'location=no');
}
});
$rootScope.$on('$cordovaPushV5:errorOccurred', function(event, error) {
console.log("notification error occured");
console.log("event object: ", event);
console.log("error object: ", error);
});
More on this github article: https://github.com/driftyco/ng-cordova/issues/1125 (code from here) and in this article: https://github.com/yafraorg/yafra/wiki/Blog-Ionic-PushV5
I want to display a "Welcome back" message on the home page after the user performs a successful signIn. However, after I make a redirect with Router.go('home');, I can't read the Session within my Template.home.rendered = function().
Here is my code:
Login logic:
Meteor.loginWithPassword(username, password, function(err) {
if (err) {
showError();
} else {
Session.set('signInSuccess', true);
Router.go('home');
}
});
Template.home.rendered = function() {
console.log(Session.get('signInSuccess'));
if (Session.get('signInSuccess') == true) {
showWelcomeMessage();
Session.set('signInSuccess', null);
}
}
Any help would be greatly appreciated.
This is simply because Template.home.rendered is executed exactly once when your template is first inserted in the DOM (it may get executed again if the template is destroyed and reinserted, via the routing mechanism).
See rendered behavior here : http://docs.meteor.com/#template_rendered
Try wrapping your verification code inside an autorun :
Template.home.rendered=function(){
// setup a reactive computation to watch for Session variable modification
this.autorun(functon(){
// using Session.equals is better than checking against Session.get
// see http://docs.meteor.com/#session_equals
if(Session.equals("signInSuccess",true)){
showWelcomeMessage();
Session.set("signInSuccess",false);
}
});
};
I am writing a short application for exporting events to Google calendar. (Events are obtained from code processing information from my website.) However, when I click the button, the script I wrote is giving me a strange error. The error I get the first time I click the button is: Uncaught TypeError: Cannot call method 'setApiKey' of undefined. However, the second time I click the button without refreshing the page, the error disappears and the code runs perfectly.
Here is my code, as you can see I defined the api key before setting it:
var exportCalendarToGoogle = function() {
var clientId = '38247913478902437.google#user...';
var scope = 'https://www.googleapis.com/auth/calendar';
var apiKey = 'JDKLSFDIOP109321403AJSL';
var withGApi = function() {
gapi.client.setApiKey(apiKey);
gapi.auth.init(checkAuth);
}
var checkAuth = function() {
gapi.auth.authorize({client_id: clientId, scope: scope, immediate: false}, handleAuthResult);
}
var handleAuthResult = function(authResult) {
if(authResult) {
gapi.client.load("calendar", "v3", exportCalendar);
} else {
alert("Authentication failed: please enter correct login information.");
}
}
//functions to format the calendar json input to Google calendar...
Sounds like gapi has not been fully loaded
http://code.google.com/p/google-api-javascript-client/wiki/GettingStarted
There are two callbacks:
1) In the URL to load the gapi code:
<script src="https://apis.google.com/js/client.js?onload=handleClientLoad"></script>
2) You can also supply a callback function that will let you know when a specific API has loaded:
gapi.client.load('plus', 'v1', function() { console.log('loaded.'); });
I think your problem is 1)