如何使用Cordova插件将Facebook身份验证详细信息发送到Firebase Firebase模板 [英] How to send Facebook authentication details to Firebase using a Cordova plugin & Firebase template

查看:462
本文介绍了如何使用Cordova插件将Facebook身份验证详细信息发送到Firebase Firebase模板的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对不起这个问题有点长,这是因为我一直在尝试解决这个问题一段时间,并希望确保我不留任何信息。我正在构建一个Cordova应用程序,并使用Firebase的身份验证/数据库后端。我一直尝试使用Facebook登录按钮将用户验证到Firebase几乎一个星期,但是我还是无法使用它。



最初我尝试了以下Firebase的示例: https://firebase.google.com / docs / auth / web / facebook-login (我需要使用高级:手动处理登录流程,因为它是Cordova Android& iOS应用程序),此示例不适用于我因为到Facebook的SDK脚本(//connect.facebook.net/en_US/sdk.js)的链接不断出现错误:



文件: //connect.facebook.net/en_US/sdk.js无法加载资源:net :: ERR_FILE_NOT_FOUND



我尝试修复此错误在几种方式,例如:




  • 将其更改为 https://connect.facebook.net/en_US/sdk.js (导致错误:无法加载网址:域的网址不包含在应用程式的网域中。要加载此网址,请将您应用的所有网域和子网域添加到应用设置中的应用域名字段。

  • 添加了相关链接

  • 将文件存储在我的本地文件系统(本地位于我手机上的应用程序内部)

  • 将整个SDK包含在我的index.html文件的头部



这些尝试都无效。所以我决定使用插件cordova-plugin-facebook从这里: https:// github。 com / bisrael / cordova-plugin-facebook



这是我用来从Facebook获取用户信息的代码:

  function logInWithFacebook(){
CordovaFacebook.login({
onSuccess:function(result){

//存储或发送用户授权/访问密钥?
//获取用户名
retrieveUserDetails();
if(result.declined.length> 0){
alert(用户拒绝了某个!);
}
},
onFailure:function(result){
if(result.cancelled){
alert(用户不喜欢我的应用程序);
} else if(result.error){
alert(有一个错误:+ result.errorLocalized);
}
}
});
}

function retrieveUserDetails(){
//现在用户已经验证了应用程序,向CordovaFacebook插件请求获取用户名
CordovaFacebook.graphRequest {
path:'/ me',
params:{fields:'name'},
onSuccess:function(userData){
console.log(userData);
console.log(userData.name);
//这里以某种方式发送检索的用户名并发送到Firebase函数,以便它与auth键链接
},
onFailure :function(result){
if(result.error){
Error.log('error','图形请求中有一个错误:'+ result.errorLocalized);
}
}
});
}

现在我可以点击登录按钮并成功登录通过Facebook。该过程正在从Facebook返回用户auth /访问密钥和用户的名称。



根据我的理解,手动登录流程示例在Firebase的文档=https://firebase.google.com/docs/auth/web/facebook-login =nofollow noreferrer> https://firebase.google.com/docs/auth/web/facebook-login a>)使用从Facebook返回的密钥,将其转换为Firebase密钥,然后将用户新创建的Firebase密钥及其用户名输入Firebase的服务器。



在下面的示例代码中非常直接:

  function checkLoginState(event){
if(event.authResponse){
//用户已登录Facebook。
var unsubscribe = firebase.auth()。onAuthStateChanged(function(firebaseUser){
unsubscribe();
//检查我们是否已经使用正确的用户登录Firebase
if(!isUserEqual(event.authResponse,firebaseUser)){
//使用Facebook验证令牌创建Firebase凭据
var credential = firebase.auth.FacebookAuthProvider.credential(
event .authResponse.accessToken);
//使用Facebook用户的凭证登录
firebase.auth()。signInWithCredential(credential).catch(function(error){
//在这里处理错误
var errorCode = error.code;
var errorMessage = error.message;
//使用的用户帐户的电子邮件
var email = error.email ;
//使用的firebase.auth.AuthCredential类型
var credential = error.credential;
// ...
});
} else {
//用户已经使用正确的用户登录Firebase。
}
});
} else {
//用户已注销Facebook。
firebase.auth()。signOut();
}
}

function isUserEqual(facebookAuthResponse,firebaseUser){
if(firebaseUser){
var providerData = firebaseUser.providerData;
for(var i = 0; i< providerData.length; i ++){
if(providerData [i] .providerId === firebase.auth.FacebookAuthProvider.PROVIDER_ID&&
providerData [i] .uid === facebookAuthResponse.userID){
//我们不需要重新验证Firebase连接。
return true;
}
}
}
return false;
}

FB.Event.subscribe('auth.authResponseChange',checkLoginState);我的问题是,如何发送从Cordova插件代码返回的auth密钥和用户名,以及如何使用这个方法来创建一个新的用户名和密码,如下图所示:?





Firebase的示例代码包含此监听器,监听Facebook授权状态的任何更改: FB.Event .subscribe('auth.authResponseChange',checkLoginState); 但因为这使用Facebook的SDK,它将无法与我当前的设置。



我使用以下Firebase聊天应用程序作为工作模板: https://gist.github .com / puf / 8f67d3376d80ed2d02670d20bfc4ec7d 你可以看到它有一个登录Facebook按钮,但没有处理的过程的代码,我试图应用手动登录流程示例中的部分在Firebase的文档( https://firebase.google.com/docs/auth/web/facebook-login )与cordova-plugin-facebook查询返回的数据,并将这两者与Firebase的聊天应用程序模板集成。



我真的感到失望接下来,我试过了我能想到的一切。任何帮助解决这个问题将真的,真的很感激。
提前感谢!



UPDATE



问题与答案:



此时如何工作?



一个Facebook登录按钮 - 当点击它运行 logInWithFacebook()。此函数使用 CordovaFacebook 插件,它还在用户使用Facebook登录后运行函数 retrieveUserDetails() retrieveUserDetails()从Facebook获取一些用户信息,我希望然后插入到我的Firebase数据库。



logInWithFacebook()可正常运作(打开Facebook登入页面, 'm能够console.log用户的Facebook ID和Facebook访问令牌。



retrieveUserDetails()



/ p>

我很高兴这个过程的前半部分工作(使用Facebook登录和检索用户详细信息正常工作)。但是我想要这个登录触发Firebase的验证状态更改侦听器,以便Firebase检测并确认用户已登录:

  firebase.auth()。 onAuthStateChanged(function(user){
if(user){
console.log(User is signed in。);
} else {
console.log没有登录);
}
});



这个过程的前半部分工作正常,但是当我谈到什么与从Facebook返回的accessToken有关。阅读文档我认为Firebase应该将这个令牌转换为一个Firebase访问令牌,然后用于将用户登录到Firebase(这也将触发上述AuthStateChanged函数)。从那里,我想能够将我从Facebook检索到的任何数据(用户名等)插入我的Firebase数据库。但是主要的问题是将Facebook accessToken转换为Firebase登录(我原来的问题中的第二个代码块是我试图执行转换/登录到Firebase)。



因为我使用Cordova,这种方法(使用插件登录到Facebook,然后处理accessToken的转换)似乎是使用Facebook登录的唯一方法。但我完全失去了如何完成下半场。



UPDATE 2



-token-to-Firebase-token代码,以便不需要Facebook SDK。它似乎是工作。这是删除SDK相关部分后的代码:

  //首先,定义Facebook accessToken:
var FBaccessToken = result.accessToken;

//使用Facebook身份验证令牌构建Firebase凭据。
var credential = firebase.auth.FacebookAuthProvider.credential(
FBaccessToken);
//使用Facebook用户的凭据登录。
firebase.auth()。signInWithCredential(credential).then(function(user){

console.log(看起来我们正确地使用Facebook令牌登录Firebase。 ;

},function(error){
console.log(出错了,用户没有使用FB令牌登录到Firebase);
//在这里处理错误
var errorCode = error.code;
var errorMessage = error.message;
//使用的用户帐户的电子邮件
var email = error.email ;
//使用的firebase.auth.AuthCredential类型。
var credential = error.credential;
// ...
});



我还需要添加用户的电子邮件从Facebook并尝试发送,同时登录到Firebase太 - 因此我将在Firebase控制台中为用户提供一些标识符,但这是一个好的开始。



第二个UPDATE



以下代码在用户授权应用后从Facebook成功获取用户数据:

  CordovaFacebook.graphRequest({
path:'/ me',
params:{fields:'first_name,last_name,email,locale,sex,age_range,picture.width(200).height )'},
onSuccess:function(userData){
console.log(userData)
var first_name = userData.first_name;
var last_name = userData.last_name;
var email = userData.email;
var locale = userData.locale;
var gender = userData.gender;
var min_age = userData.age_range.min;
var profile_picture = userData.picture.data.url;

//在Firebase数据库中输入用户详细信息:
firebase.database()。ref('users /'+ uid).set({
first_name:first_name,
last_name:last_name,
email:email,
locale:locale,
gender:gender,
min_age:min_age,
profile_picture:profile_picture
});
console.log(Facebook用户数据现在应该在数据库!);
},
onFailure:function(result){
if(result.error){
Error.log('error',' + result.errorLocalized);
}
}
});


解决方案



如何从CordovaFacebook.login()获取用户电子邮件



查看 CordovaFacebook文档,您可以添加 $ 方法



>根据 Facebook API文档,电子邮件的权限名称只是电子邮件



我没有测试,但我认为这应该工作:

  CordovaFacebook.login({
permissions:['email'],
onSuccess:function结果){
console.log('email:',result.email);
...
},
onFailure:function(result){
。 ..
}
});


Sorry this question is kind of long, it's because I've been trying to solve this problem for a while and want to make sure I don't leave any info out. I'm building a Cordova app and using Firebase for the authentication/database back end. I've been trying to authenticate users into Firebase using a Log in with Facebook button for almost a week now, but I haven't been able to get it to work.

Originally I tried following Firebase's example here: https://firebase.google.com/docs/auth/web/facebook-login (I need to use the "Advanced: Handle the sign in flow manually" as it is a Cordova Android & iOS app), this example didn't work for me as the link to Facebook's SDK script (//connect.facebook.net/en_US/sdk.js) kept throwing the error:

file://connect.facebook.net/en_US/sdk.js Failed to load resource: net::ERR_FILE_NOT_FOUND

I tried to fix this error in several ways, such as:

  • Changing it to https://connect.facebook.net/en_US/sdk.js (this resulted in the error: Can't Load URL: The domain of this URL isn't included in the app's domains. To be able to load this URL, add all domains and subdomains of your app to the App Domains field in your app settings. )
  • Added the links in question to the list of "Valid OAuth redirect URIs" and domains in the Facebook app settings
  • Storing the file in my local file system (and locally inside the app on my phone)
  • Including the entire SDK inside the head of my index.html file

None of these attempts worked. So instead I decided to use the plugin cordova-plugin-facebook from here: https://github.com/bisrael/cordova-plugin-facebook

This is the code I'm using to get the user's information from Facebook with the plugin:

function logInWithFacebook(){
    CordovaFacebook.login({
    onSuccess: function(result) {
         console.log(result);
         console.log(result.authToken);
         // Store or send the user auth/access key here?
         // Get user's name
         retrieveUserDetails(); 
    if(result.declined.length > 0) {
         alert("The User declined something!");
      }
   },
   onFailure: function(result) {
      if(result.cancelled) {
         alert("The user doesn't like my app");
      } else if(result.error) {
         alert("There was an error:" + result.errorLocalized);
      }
   }
});
}

function retrieveUserDetails(){
    // Now that the user has authroised the app, make request to CordovaFacebook plugin to get user's name
    CordovaFacebook.graphRequest({
        path: '/me',
        params: { fields: 'name' },
        onSuccess: function (userData) {
            console.log(userData);
            console.log(userData.name);
        // Here somehow send the retrieved username and send it to the Firebase function so that it's linked with the auth key.
        },
        onFailure: function (result) {
            if (result.error) {
                Error.log('error', 'There was an error in graph request:' + result.errorLocalized);
            }
        }
    });
}

I'm now able to click on a log in button and log in successfully through Facebook. That process is returning a user auth/access key and the user's name from Facebook.

As I understand it, the manual log in flow example in Firebase's docs (https://firebase.google.com/docs/auth/web/facebook-login) takes the key returned from Facebook, converts it into a Firebase key, and then enters the user's newly created Firebase key and their username into Firebase's servers.

This seems pretty straight forward in the following sample code:

function checkLoginState(event) {
  if (event.authResponse) {
    // User is signed-in Facebook.
    var unsubscribe = firebase.auth().onAuthStateChanged(function(firebaseUser) {
      unsubscribe();
      // Check if we are already signed-in Firebase with the correct user.
      if (!isUserEqual(event.authResponse, firebaseUser)) {
        // Build Firebase credential with the Facebook auth token.
        var credential = firebase.auth.FacebookAuthProvider.credential(
            event.authResponse.accessToken);
        // Sign in with the credential from the Facebook user.
        firebase.auth().signInWithCredential(credential).catch(function(error) {
          // Handle Errors here.
          var errorCode = error.code;
          var errorMessage = error.message;
          // The email of the user's account used.
          var email = error.email;
          // The firebase.auth.AuthCredential type that was used.
          var credential = error.credential;
          // ...
        });
      } else {
        // User is already signed-in Firebase with the correct user.
      }
    });
  } else {
    // User is signed-out of Facebook.
    firebase.auth().signOut();
  }
}

function isUserEqual(facebookAuthResponse, firebaseUser) {
  if (firebaseUser) {
    var providerData = firebaseUser.providerData;
    for (var i = 0; i < providerData.length; i++) {
      if (providerData[i].providerId === firebase.auth.FacebookAuthProvider.PROVIDER_ID &&
          providerData[i].uid === facebookAuthResponse.userID) {
        // We don't need to re-auth the Firebase connection.
        return true;
      }
    }
  }
  return false;
}

FB.Event.subscribe('auth.authResponseChange', checkLoginState);

My question is, how can I send the auth key and username returned from the Cordova plugin code, to Firebase's example code so that it works smoothly?

Firebase's example code includes this listener which listens for any change in the Facebook authorization status: FB.Event.subscribe('auth.authResponseChange', checkLoginState); but as this uses Facebook's SDK it won't work with my current set up.

I'm using the following Firebase chat app as a template to work from: https://gist.github.com/puf/8f67d3376d80ed2d02670d20bfc4ec7d as you can see it has a Login with Facebook button, but no code for handling the process, I'm trying to apply parts of the manual log in flow example in Firebase's docs (https://firebase.google.com/docs/auth/web/facebook-login) with data returned from the cordova-plugin-facebook queries, and integrate both with Firebase's chat app template.

I'm really at a loss as to what to do next, I've tried everything I can think of. Any help in solving this problem would be really, really appreciated. Thank you in advance!

UPDATE

Questions and answers:

How does it work at the moment?

Right now I have a "Facebook Login" button - when this is clicked it runs logInWithFacebook(). This function uses the CordovaFacebook plugin, it also runs the function retrieveUserDetails() after the user signs in with Facebook. retrieveUserDetails() gets some user info from Facebook which I hope to then insert into my Firebase database.

logInWithFacebook() works correctly (it opens up a Facebook login page, and when the user logs in, I'm able to console.log the user's Facebook ID, and the Facebook access Token.

retrieveUserDetails() also works correctly (I'm able to console.log the user's name taken from Facebook).

How do you want it to work?

I'm happy with how the first half of the process is working (the logging in with Facebook and retrieving user details is working correctly). However I want this log in to trigger Firebase's auth state change listener, so that Firebase detects and confirms that the user has logged in:

firebase.auth().onAuthStateChanged(function(user) {
  if (user) {
    console.log("User is signed in.");
  } else {
    console.log("User is not signed in.");
  }
});

What is not working the way you want?

The first half of the process is working correctly, but I'm lost when it comes to what to do with the accessToken returned from Facebook. From reading the docs I think that Firebase is supposed to convert this token into a Firebase access token, and then that is used to log the user into Firebase (this would also trigger the above AuthStateChanged function). From there I want to be able to insert any data I've retrieved from Facebook (the user's name etc) into my Firebase database. But the main problem is getting the Facebook accessToken converted into a Firebase login (the second block of code in my original question is where I'm trying to perform the conversion/sign into Firebase).

Because I'm using Cordova, this method (logging into Facebook with a plugin and then handling the conversion of the accessToken) seems to be the only way to log in with Facebook. But I'm totally lost on how to complete the second half.

UPDATE 2

I've trimmed parts from the sample convert-Facebook-token-to-Firebase-token code from the docs so that the Facebook SDK isn't required. And it appears to be working. This is the code after cutting away the SDK related parts:

// First, define the Facebook accessToken:
var FBaccessToken = result.accessToken;

// Build Firebase credential with the Facebook auth token.
var credential = firebase.auth.FacebookAuthProvider.credential(
    FBaccessToken);
// Sign in with the credential from the Facebook user.
firebase.auth().signInWithCredential(credential).then(function(user){

console.log("It looks like we signed into Firebase with the Facebook token correctly.");

}, function(error) {
    console.log("Something went wrong, user isn't signed into Firebase with the FB token.");
  // Handle Errors here.
  var errorCode = error.code;
  var errorMessage = error.message;
  // The email of the user's account used.
  var email = error.email;
  // The firebase.auth.AuthCredential type that was used.
  var credential = error.credential;
  // ...
});

I still need to add the user's email from Facebook and try to send that while logging into Firebase too - so that I'll have some identifier for the user in the Firebase console, but this is a good start.

2nd UPDATE

The below code successfully gets user data from Facebook after the user authorizes the app:

    CordovaFacebook.graphRequest({
    path: '/me',
    params: { fields: 'first_name,last_name,email,locale,gender,age_range,picture.width(200).height(200)' },
    onSuccess: function (userData) {
        console.log(userData)
        var first_name = userData.first_name;
        var last_name = userData.last_name;
        var email = userData.email;
        var locale = userData.locale;
        var gender = userData.gender;
        var min_age = userData.age_range.min;
        var profile_picture = userData.picture.data.url;

            // Enter user details into the Firebase database:
            firebase.database().ref('users/' + uid).set({
            first_name: first_name,
            last_name: last_name,
            email: email,
            locale: locale,
            gender: gender,
            min_age: min_age,
            profile_picture : profile_picture
        });
        console.log("Facebook user data should now be in the database!");   
    },
    onFailure: function (result) {
        if (result.error) {
            Error.log('error', 'There was an error in graph request:' + result.errorLocalized);
        }
    }
});

解决方案

(Just an answer to the last update, as you figured out the rest :))

How to get user email from CordovaFacebook.login()

Looking at the CordovaFacebook documentation you can add a permissions property on the object passed to the login method.

According to the Facebook API documentation the permission name for email is just "email".

I haven't tested, but I think this should work:

CordovaFacebook.login({
    permissions: [ 'email' ],
    onSuccess: function(result) {
        console.log('email:', result.email);
        ...
    },
    onFailure: function(result) {
        ...
    }
});

这篇关于如何使用Cordova插件将Facebook身份验证详细信息发送到Firebase Firebase模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆