问题:在Android设备上安装Facebook本机应用程序时,Facebook登录停止工作
涉及的实体: 1. Facebook登录 2.科尔多瓦应用程序 3. InAppBrowser 4. Android(版本5.1) 5. Facebook原生应用
观察:
点击登录按钮时显示空白屏幕
提供了两个日志摘录(最后)。第一个是非常标准的(应用程序初始化期间的那个)。在第二个日志中,InAppBrowser的loadstart事件后面紧跟一个loadstop事件。这会导致一个空白页面。
使用的代码源自OpenFb(https://github.com/ccoenraets/OpenFB)。代码在本问题的最后提供(在日志下面)。
a)为什么在'loadstart'之后立即调用'loadstop'(没有任何延迟) - 安装facebook native app时?
b)它与facebook app的深层链接有什么关系吗?
c)可能的决议将不胜感激。
PS ......关于SO的其他类似问题没有答案。
附录(日志和代码)
从应用初始化登录(虽然这里没有任何独特之处)
I/WebViewFactory(20666): Loading com.google.android.webview version 57.0.2987.132 (code 298713250)
I/art (20666): Rejecting re-init on previously-failed class java.lang.Class<com.android.webview.chromium.TokenBindingManagerAdapter>
...
I/art (20666): Rejecting re-init on previously-failed class
...
D/WebView (20666): WebView<init>
D/WebView (20666): setInitialScale=0
D/SystemWebViewEngine(20666): CordovaWebView is running on device made by: OPPO
D/WebView (20666): addJavascriptInterface=_cordovaNative
D/CordovaWebViewImpl(20666): >>> loadUrl(file:///android_asset/www/index.html)
D/WebView (20666): loadUrl=file:///android_asset/www/index.html
D/WebView (20666): onResume
...
D/CordovaWebViewImpl(20666): onPageDidNavigate(file:///android_asset/www/index.html)
...
D/CordovaWebViewImpl(20666): onPageFinished(file:///android_asset/www/index.html#/)iew (20666): evaluateJavascript=cordova.callbackFromNative('InAppBrowser114205225',true,1,[{"type":"loadstop","url":"https:\/\/www.halfchess.com\/auth\/facebook?r=https%3A%2F%2Fwww.halfchess.com%2F"}],true);
单击“登录”按钮时记录。
D/SystemWebChromeClient(20666): file:///android_asset/www/bundle.js: Line 76246 : LOGIN_ATTEMPT
D/WebView (20666): WebView<init>
D/WebView (20666): loadUrl=https://www.halfchess.com/auth/facebook?r=https%3A%2F%2Fwww.halfchess.com%2F
D/WebView (20666): evaluateJavascript=cordova.callbackFromNative('InAppBrowser114205225',true,1,[""],true);
V/InputMethodManager(20666): onWindowFocus: android.webkit.WebView{11dadeb5 VFEDHVC. .F....ID 0,0-720,1244 #6} softInputMode=16 first=true flags=#0
V/InputMethodManager(20666): START INPUT: android.webkit.WebView{11dadeb5 VFEDHVC. .F....ID 0,0-720,1244 #6} ic=null tba=android.view.inputmethod.EditorInfo@604488f controlFlags=#105
D/WebView (20666): evaluateJavascript=cordova.callbackFromNative('InAppBrowser114205225',true,1,[{"type":"loadstart","url":"https:\/\/www.halfchess.com\/auth\/facebook?r=https%3A%2F%2Fwww.halfchess.com%2F"}],true);
D/SystemWebChromeClient(20666): file:///android_asset/www/bundle.js: Line 39091 : loadHandler: https://www.halfchess.com/auth/facebook?r=https%3A%2F%2Fwww.halfchess.com%2F
D/WebView (20666): evaluateJavascript=cordova.callbackFromNative('InAppBrowser114205225',true,1,[{"type":"loadstop","url":"https:\/\/www.halfchess.com\/auth\/facebook?r=https%3A%2F%2Fwww.halfchess.com%2F"}],true);
应用程序中使用的代码
function cordovaFbLogin(redirectUrl) {
const promise = new Promise((resolve, reject) => {
//console.log('Inside cordovaFbLoginApi');
let loginWindow = window.open(
`${fbLoginUrl}?r=${redirectUrl}`,
'_blank',
'location=no,hardwareback=no,clearsessioncache=yes');
const startTime = new Date().getTime();
let isPending = true;
let visitedFacebook = false;
const loadHandler = (event) => {
const url = event.url;
console.log('loadHandler: ' + url);
if (url.indexOf('https://www.facebook.com') === 0) {
visitedFacebook = true;
return;
}
// NOTE: redirection sequence is a follows
// facebook domain --> Halfchess --> redirectUrl
// We close the window at '2nd step' (see below)
if (url.indexOf('https://halfchess.com') === 0 && visitedFacebook) {
// exit when the browser redirects back to us
if (url.indexOf('code=') > 0) {
// we have the cookie - make next API call or reject
isPending = false;
resolve();
} else if (url.indexOf('error=') > 0) {
isPending = false;
reject();
}
}
if (!isPending) {
// in the Cordova app, and trying to close it while it's animating
// generates an exception. Wait a little...
const timeout = 600 - (new Date().getTime() - startTime);
setTimeout(() => {
loginWindow.close();
}, timeout > 0 ? timeout : 0);
}
};
const loadError = (error) => {
console.log('fbLogin window - load error')
console.log(error);
}
const exitHandler = () => {
console.log('fbLogin window - exit');
loginWindow.removeEventListener('loaderror', loadError)
loginWindow.removeEventListener('loadstart', loadHandler)
loginWindow.removeEventListener('exit', exitHandler)
loginWindow.close();
loginWindow = undefined;
};
loginWindow.addEventListener('loadstart', loadHandler);
loginWindow.addEventListener('loaderror', loadError);
loginWindow.addEventListener('exit', exitHandler);
});
return promise;
}
答案 0 :(得分:0)
我终于使用了一个解决方案,我会检测到我是否有一个Facebook应用程序(同样使用的插件是cordova-plugin-appavailability)然后按照以下流程之一: -
如果我有原生的fb应用,请使用cordova-plugin-facebook4。客户端从facebook接收令牌并将其传递给服务器(我创建了一条新路由)
如果我没有原生的fb应用程序,那么我使用上面编写的函数(或者自上次发布以来对其进行重构的变体)。
我们需要实施这两种方法,因为(1)如果没有facebook原生应用程序将无法工作;(2)如果手机上有本机应用程序,则无效。