1. Android용 Facebook SDK 다운로드에서 다음
선택
2. Facebook SDK 가져오기
build.gradle (Project)
의 repositories
에 추가mavenCentral()
build.gradle (Module: app)
의 dependencies
에 추가implementation 'com.facebook.android:facebook-android-sdk:[4,5)'
3. Android 프로젝트에 대해 Facebook에 알리기
https://stackoverflow.com/questions/7506392/how-to-create-android-facebook-key-hash
fun printHashKey() {
try {
val info: PackageInfo = packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES)
for (signature in info.signatures) {
val md: MessageDigest = MessageDigest.getInstance("SHA")
md.update(signature.toByteArray())
val hashKey: String = String(Base64.encode(md.digest(), 0))
Log.i("TAG", "printHashKey() Hash Key: $hashKey")
}
} catch (e: NoSuchAlgorithmException) {
Log.e("TAG", "printHashKey()", e)
} catch (e: Exception) {
Log.e("TAG", "printHashKey()", e)
}
}
👉 Hash
값을 얻기 위한 함수!
onCreate()
에서 printHashKey()
실행Logcat
에 Tag
검색하면 다음과 같이 Hash Key
확인 가능4. 개발 및 릴리스 키 해시 추가
Hash key
추가5. 앱에 대한 SSO 활성화
예
로 설정6. 리소스 및 메니페스트 수정
app/res/values/strings.xml
에 id
, protocol_scheme
추가/app/manifest/AndroidManifest.xml
에 권한 추가
<uses-permission android:name="android.permission.INTERNET"/>
application
요소 내에 추가 <meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="@string/facebook_app_id" />
<activity
android:name="com.facebook.FacebookActivity"
android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
android:label="@string/app_name" />
<activity
android:name="com.facebook.CustomTabActivity"
android:exported="true">
<intent-filter><action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="@string/fb_login_protocol_scheme" />
</intent-filter>
</activity>
Firebase
의 Authentication
> Sign-in-method
에 페이스북 정보 매핑시키기
OAuth 리디렉션 URI 복사해서 붙여넣기 (Firebase → Facebook)
설정 > 기본 설정
에서 앱 ID와 앱 시크릿 코드 복사해서 붙여넣기 (Facebook → Firebase)
설정 끝!
facebookLogin
함수fun facebookLogin() {
// 페이스북에서 받을 권한 요청 - 프로필 이미지, 이메일
LoginManager.getInstance()
.logInWithReadPermissions(this, Arrays.asList("public_profile", "email"))
// LoginResult : 페이스북 로그인이 최종 성공했을 때 넘어오는 부분
LoginManager.getInstance()
.registerCallback(callbackManager, object : FacebookCallback<LoginResult>{
override fun onSuccess(result: LoginResult?) {
// Second step
// 로그인이 성공하면 페이스북 데이터를 파이어베이스에 넘기는 함수
handleFacebookAccessToken(result?.accessToken)
}
override fun onCancel() {
}
override fun onError(error: FacebookException?) {
}
})
}
handleFacebookAccessToken
함수// facebook 데이터를 firebase에 넘김
fun handleFacebookAccessToken(token : AccessToken?) {
var credential = FacebookAuthProvider.getCredential(token?.token!!)
auth?.signInWithCredential(credential)
?.addOnCompleteListener {
task ->
if(task.isSuccessful) {
// Third step
// Login, 아이디와 패스워드가 맞았을 때
// Toast.makeText(this, "success", Toast.LENGTH_LONG).show()
moveMainPage(task.result?.user)
} else {
// Show the error message, 아이디와 패스워드가 틀렸을 때
Toast.makeText(this, task.exception?.message, Toast.LENGTH_LONG).show()
}
}
}
package org.techtown.howlstagram_f16
import android.app.Activity
import android.content.ContentValues.TAG
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import com.google.android.gms.auth.api.Auth
import com.google.android.gms.auth.api.signin.GoogleSignIn
import com.google.android.gms.auth.api.signin.GoogleSignInAccount
import com.google.android.gms.auth.api.signin.GoogleSignInClient
import com.google.android.gms.auth.api.signin.GoogleSignInOptions
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.FirebaseUser
import com.google.firebase.auth.GoogleAuthProvider
import kotlinx.android.synthetic.main.activity_login.*
import android.content.pm.PackageManager
import android.content.pm.PackageInfo
import android.util.Base64
import android.util.Log
import com.facebook.AccessToken
import com.facebook.CallbackManager
import com.facebook.FacebookCallback
import com.facebook.FacebookException
import com.facebook.login.LoginManager
import com.facebook.login.LoginResult
import com.google.firebase.auth.FacebookAuthProvider
import java.lang.Exception
import java.security.MessageDigest
import java.security.NoSuchAlgorithmException
import java.util.*
class LoginActivity : AppCompatActivity() {
// firebase 인증을 위한 변수
var auth : FirebaseAuth? = null
// 구글 로그인 연동에 필요한 변수
var googleSignInClient : GoogleSignInClient? = null
var GOOGLE_LOGIN_CODE = 9001
// 페이스북 로그인 결과를 가져오는 callbackManager
var callbackManager : CallbackManager? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login)
auth = FirebaseAuth.getInstance()
email_login_button.setOnClickListener {
signinAndSignup()
}
google_sign_in_button.setOnClickListener {
//First step
googleLogin()
}
facebook_login_button.setOnClickListener {
// First step
facebookLogin()
}
// 사용자 ID와 프로필 정보를 요청하기 위해 gso를 인자로 전달해서 GoogleSignInClient 객체 생성
var gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id))
.requestEmail()
.build()
googleSignInClient = GoogleSignIn.getClient(this, gso)
// printHashKey() // 해시 키 가져오는 함수
// 로그인 응답을 처리할 CallbackManager
callbackManager = CallbackManager.Factory.create()
}
fun printHashKey() {
try {
val info: PackageInfo = packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES)
for (signature in info.signatures) {
val md: MessageDigest = MessageDigest.getInstance("SHA")
md.update(signature.toByteArray())
val hashKey: String = String(Base64.encode(md.digest(), 0))
Log.i("TAG", "printHashKey() Hash Key: $hashKey")
}
} catch (e: NoSuchAlgorithmException) {
Log.e("TAG", "printHashKey()", e)
} catch (e: Exception) {
Log.e("TAG", "printHashKey()", e)
}
}
// googleSignInClient를 signInIntent 메소드를 통해서 signInIntent를 만들고, startActivityForResult에 전달
// 새 액티비티를 열고, 결과 값 전달 => onActivityResult()가 결과 값 받음
// 사용자가 signIn에 성공하면 onActivityResult() 실행
fun googleLogin() {
var signInIntent = googleSignInClient?.signInIntent
startActivityForResult(signInIntent, GOOGLE_LOGIN_CODE)
}
fun facebookLogin() {
// 페이스북에서 받을 권한 요청 - 프로필 이미지, 이메일
LoginManager.getInstance()
.logInWithReadPermissions(this, Arrays.asList("public_profile", "email"))
// LoginResult : 페이스북 로그인이 최종 성공했을 때 넘어오는 부분
LoginManager.getInstance()
.registerCallback(callbackManager, object : FacebookCallback<LoginResult>{
override fun onSuccess(result: LoginResult?) {
// Second step
// 로그인이 성공하면 페이스북 데이터를 파이어베이스에 넘기는 함수
handleFacebookAccessToken(result?.accessToken)
}
override fun onCancel() {
}
override fun onError(error: FacebookException?) {
}
})
}
// facebook 데이터를 firebase에 넘김
fun handleFacebookAccessToken(token : AccessToken?) {
var credential = FacebookAuthProvider.getCredential(token?.token!!)
auth?.signInWithCredential(credential)
?.addOnCompleteListener {
task ->
if(task.isSuccessful) {
// Third step
// Login, 아이디와 패스워드가 맞았을 때
// Toast.makeText(this, "success", Toast.LENGTH_LONG).show()
moveMainPage(task.result?.user)
} else {
// Show the error message, 아이디와 패스워드가 틀렸을 때
Toast.makeText(this, task.exception?.message, Toast.LENGTH_LONG).show()
}
}
}
// requestCode == 구글 로그인 코드
// result에 구글에 로그인했을 때 구글에서 넘겨주는 결과 값 저장
// result가 성공하면 firebaseAuthWithGoogle()에 결과 아이디 넘겨줌
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
// 로그인 결과를 callbackManager를 통해 loginManager에게 전달
callbackManager?.onActivityResult(requestCode, resultCode, data)
if(requestCode == GOOGLE_LOGIN_CODE) {
var result = Auth.GoogleSignInApi.getSignInResultFromIntent(data)
// result가 성공했을 때 이 값을 firebase에 넘겨주기
if(result!!.isSuccess) {
var account = result.signInAccount
// Second step
firebaseAuthWithGoogle(account)
}
}
}
// account에서 id 토큰을 가져와서 firebase 사용자 인증 정보로 교환해야 함 => signInWithCredential()
fun firebaseAuthWithGoogle(account : GoogleSignInAccount?) {
var credential = GoogleAuthProvider.getCredential(account?.idToken,null)
auth?.signInWithCredential(credential)
?.addOnCompleteListener {
task ->
if(task.isSuccessful) {
// Login, 아이디와 패스워드가 맞았을 때
// Toast.makeText(this, "success", Toast.LENGTH_LONG).show()
moveMainPage(task.result?.user)
} else {
// Show the error message, 아이디와 패스워드가 틀렸을 때
Toast.makeText(this, task.exception?.message, Toast.LENGTH_LONG).show()
}
}
}
// email과 password를 받아오고 addOnCompleteListener로 성공 유무의 값을 받아 성공하면 메인페이지로 이동
fun signinAndSignup() {
auth?.createUserWithEmailAndPassword(email_edittext.text.toString(),password_edittext.text.toString())
?.addOnCompleteListener {
task ->
if(task.isSuccessful) {
// Creating a user account
moveMainPage(task.result?.user)
} else if(task.exception?.message.isNullOrEmpty()) {
// Show the error message
Toast.makeText(this, task.exception?.message, Toast.LENGTH_LONG).show()
} else {
// Login if you have account
signinEmail()
}
}
}
fun signinEmail() {
auth?.signInWithEmailAndPassword(email_edittext.text.toString(),password_edittext.text.toString())
?.addOnCompleteListener {
task ->
if(task.isSuccessful) {
// Login, 아이디와 패스워드가 맞았을 때
moveMainPage(task.result?.user)
} else {
// Show the error message, 아이디와 패스워드가 틀렸을 때
Toast.makeText(this, task.exception?.message, Toast.LENGTH_LONG).show()
}
}
}
// 로그인이 성공하면 다음 페이지로 넘어가는 함수
fun moveMainPage(user:FirebaseUser?) {
// 파이어베이스 유저 상태가 있을 경우 다음 페이지로 넘어갈 수 있음
if(user != null) {
startActivity(Intent(this, MainActivity::class.java))
}
}
}
🆘 For your account security, logging into Facebook from an embedded browser is disabled. You may be able to continue by updating the app you're logging in from and trying again.
계정 보안을 위해 내장 브라우저에서 Facebook에 로그인하는 것은 비활성화되었다고 한다.
찾아보니까 다른 브라우저를 이용하거나 테스트 사용자로 어떻게 하라는데 뭐가 뭔지 몰라서 계속 구글링..
그러다 발견한 방법!
https://stackoverflow.com/questions/68026081/android-facebook-share-dialog-blocks-login-due-to-embedded-browser
dependenciese
를 다음과 같이 업데이트
implementation 'com.facebook.android:facebook-android-sdk:[8,9)'