Phone gap Facebook plugin一直要求重新登入,怎麼辦?

PhoneGap是一個讓你可以在行動裝置上能夠以HTML/CSS/JS開發的框架。支援了包括iOS,Android,Windows Mobile,甚至是BlackBerry等。但是如果你真的天真的相信它真的能夠達到跨平台的話,我大概只能祝你好運。首先Native Code的部分勢必是需要重寫的。再來每個平台的瀏覽器支援JS/CSS的程度也不同,所以光是跨iOS與Android就會有很大的問題了。更別說還要考慮Android上各種螢幕尺寸的問題。
我之所以用了PhoneGap的唯一原因是因為可以快速的實作出想要的App樣子。在有限的時間內要在單一平台上開發出一個完整App,這還是一個值得考慮的Solution。
但這裡沒有要寫教學文,網路上應該已經很多了,不過要小心的是大部分都是舊版的。PhoneGap從1.3之後有很大的改變,因此要特別小心你看的Tutorial文章用的是哪一個版本。
這裡其實是要抱怨Dave Johnson, Nitobi CTO釋放的Facebook Plugin有一個很基本但是卻很重大的問題。那就是登入過後的session cache處理有問題啊,這會導致每次app開起來都必須重新做一次facebook登入認證,然後導致很差的使用者經驗。
在罵之前還是要先說一下好話,Dave Johnson包裝的版本已經可以幫很多人省下很多的功了,只是還是不太應該埋下這個bug啊。
以下是pg-plugin-fb-connect.js中完整的source code:

 

PG = ( typeof PG == "undefined" ? {} : PG );
PG.FB = {
 init: function(apiKey, fail) {
 // create the fb-root element if it doesn"t exist
 if (!document.getElementById("fb-root")) {
 var elem = document.createElement("div");
 elem.id = "fb-root";
 document.body.appendChild(elem);
 }
 PhoneGap.exec(function() {
 var session = JSON.parse(localStorage.getItem("pg_fb_session") || "{"expires":0}");
 if (session && session.expires > new Date().valueOf()) {
 FB.Auth.setSession(session, "connected");
 }
 console.log("PhoneGap Facebook Connect plugin  initialized successfully.");
 }, (fail?fail:null), "com.phonegap.facebook.Connect", "init", [apiKey]);
 },
 login: function(params, cb, fail) {
 params = params || { perms: "" };
 PhoneGap.exec(function(e) { // login
 localStorage.setItem("pg_fb_session", JSON.stringify(e.session));
 FB.Auth.setSession(e.session, "connected");
 if (cb) cb(e);
 }, (fail?fail:null), "com.phonegap.facebook.Connect", "login", params.perms.split(",") );
 },
 logout: function(cb, fail) {
 PhoneGap.exec(function(e) {
 localStorage.removeItem("pg_fb_session");
 FB.Auth.setSession(null, "notConnected");
 if (cb) cb(e);
 }, (fail?fail:null), "com.phonegap.facebook.Connect", "logout", []);
 },
 getLoginStatus: function(cb, fail) {
 PhoneGap.exec(function(e) {
 if (cb) cb(e);
 }, (fail?fail:null), "com.phonegap.facebook.Connect", "getLoginStatus", []);
 }
};
主要的問題就在標紅字的session.expires > new Date().valueof()那裡。
這邊的流程是每次App開起來會call init,然後如果call login去做Facebook OAuth,之後會把Facebook傳回的session存到瀏覽器的local storage。所以下一次App打開的時候在init的地方就會嘗試用之前存下的session去做初始化的動作。而問題就在這,每次在紅字這一行的condition check都是false啊。原因就在session.expires是日期字串,而new Date().valueof()是數值啊。剛剛又到GitHub上看了一下,還是沒人改掉。看來晚一點要來Push一個版本上去。
修掉這個問題的方法很簡單,只要用Date Object去parse session.expires轉成timestamp之後再做condition checking就可以了。
如下修正:
var eventStamp = Date.parse(session.expires);
if (eventStamp = new Date().valueOf())
Kenny Lee


Leave a Reply

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *