またFirebaseですが、妙にはまってしまったので書き記しておきます。
FirebaseにはFacebookをはじめとしてTwitterやGoogleアカウントで認証してユーザーをつくれる便利な機能があります。
いわゆるOAuth認証なのですが、Firebase側で用意されている認証関数を使うと、そこで独自にアクセストークンをつくって認証を全部やってくれてしまうため、便利な反面、普通にやっているとその認証情報をつかってプロフィールの情報とかフレンドリストとか、FacebookのJavaScript SDKを通した、Graph API等へのアクセスと両立できません。
しかし、そこは両立させたいのでどうやったら両立できるのか、でいろいろやってハマりました。
一応、公式の
JavaScript で Facebook ログインを使用して認証する / 高度: 手動でログインフローを処理する
に書いてあるっちゃ書いてるんですが、なんかちょっと手順が複雑になってたりもするので、一番シンプルなやり方です。基本的には、先にJavaScript SDKでログインして取得したトークンでFirebase認証するだけです。
まずは、javascript SDKを使うときに書く、いつものおまじないを書きます。
単純にFirebaseの認証を使う場合はこれを書かなかったりするのですが、今回はJavaScript SDKを使うので書きます。
window.fbAsyncInit = function() {
FB.init({
appId : 'your-app-id',
xfbml : true,
version : 'v2.5'
});
};
(function(d, s, id){
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) {return;}
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/en_US/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
その後は、まずは普通にFB.login()でログインしてもらいます。
レスポンスが来たら、FB.getLoginStatus()でちゃんとログインしているかを確認します。
ログインできていたらその段階で当然、Facebookのアクセストークンを取れるのでそれを使って、firebase.auth.AuthCredentialオブジェクトをつくって、それを引数にしてsignInWithCredential()関数を実行すると、さっき普通にFB.login()して認証した情報をそのまま使ってFirebaseの認証を行うことができました。
FB.login(function(response) {
checkFBLogin(response);
}, {scope: 'public_profile,email'});
function checkFBLogin(response){
//ログインのステータスチェック
FB.getLoginStatus(function (response) {
if (response.authResponse) {
//ログインしている
//レスポンスに入っているアクセストークンを使って、firebaseのcredentialをつくる
var credential = firebase.auth.FacebookAuthProvider.credential(response.authResponse.accessToken);
//signInWithCredential()を使うと、既に存在しているアクセストークンでFirebase認証できる
firebase.auth().signInWithCredential(credential).then(function() {
//認証できた!
}).catch(function(error) {
//エラー
});
} else {
//ログインしてない
}
});
}
作業をしていたのが休み明けなのもあって、妙にハマってしまったのがこの後で、じゃあFirebaseで認証を成功させた後、どうやって自分のユーザー情報とかを取得すればいいんだ?! と思って悩みました。通常の認証だと、firebase.auth().signInWithPopup(provider).then(function(result) {
とかやってresultの中にそのへんの情報が入っているのでちょっと勝手が違います。
よく考えると当たり前で、認証が成功している段階においてはいつでもどこでも、firebase.auth().currentUserに直接アクセスすれば情報が取れます。なので下記のようになります。
firebase.auth().signInWithCredential(credential).then(function() {
//認証できた!
var _user = firebase.auth().currentUser;
console.log(_user.displayName);
}).catch(function(error) {
//エラー
});
そうすると、console.log(_user.displayName)のところでFacebookアカウントにひもづいた名前(私の場合、"Qanta Shimizu")が出力されるはずです。
と同時に、
firebase.auth().signInWithCredential(credential).then(function() {
//認証できた!
var _user = firebase.auth().currentUser;
FB.api('/me/location', function(response) {
if (!response || response.error) {
//エラーハンドリング
} else {
//Graph APIからの情報
}
});
}).catch(function(error) {
//エラー
});
みたいな感じで同時にGraph APIへのリクエストをしたりすることも可能です(例文の/me/locationの取得には、Facebookに使用申請して許可をもらう必要があります)。