#firebase #authentication #firebase-authentication
#firebase #аутентификация #firebase-аутентификация
Вопрос:
Мне нужно авторизовать пользователей с помощью Google Sign на Firebase. Но поскольку мне нужно использовать API календаря, я должен выполнить пользовательский вход в систему (а не тот, который предоставляется через Firebase по умолчанию), поскольку мне нужен токен обновления Oauth, который не предоставляется Firebase. Я просмотрел документы, но, похоже, ни один из них не работает, на данный момент я использую приведенный ниже код … кто-нибудь может подсказать, как мне использовать токен, полученный от Google, для входа / регистрации в Firebase?
private const val TAG = "WelcomeActivity"
class WelcomeActivity : AppCompatActivity() {
var firebaseUser: FirebaseUser? = null
//For Google Sign In
val RC_SIGN_IN: Int = 9001
private lateinit var mGoogleSignInClient: GoogleSignInClient
lateinit var mGoogleSignInOptions: GoogleSignInOptions
private lateinit var firebaseAuth: FirebaseAuth
private var firebaseUserID: String = ""
private lateinit var refUsers: DatabaseReference
//get data from google signin in handlesigninresult
private var googleId = ""
private var googleFirstName = ""
private var googleLastName = ""
private var googleEmail = ""
private var googleProfilePicURL = ""
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_welcome)
// //For google sign in
// configureGoogleSignIn()
// setupUI()
// enablePersistence()
firebaseAuth = FirebaseAuth.getInstance()
val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken("")
.requestEmail()
.build()
mGoogleSignInClient = GoogleSignIn.getClient(this, gso)
google_login.setOnClickListener {
signIn()
}
login_welcome.setOnClickListener {
val intent = Intent(this@WelcomeActivity, LoginActivity::class.java)
startActivity(intent)
finish()
}
}
private fun signIn() {
val signInIntent = mGoogleSignInClient.signInIntent
startActivityForResult(signInIntent, RC_SIGN_IN)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == RC_SIGN_IN) {
val task =
GoogleSignIn.getSignedInAccountFromIntent(data)
handleSignInResult(task)
}
}
private fun handleSignInResult(completedTask: Task<GoogleSignInAccount>) {
try {
val account = completedTask.getResult(
ApiException::class.java
)
// Signed in successfully
googleId = account?.id ?: ""
Log.i("Google ID", googleId)
googleFirstName = account.givenName ?: ""
Log.i("Google First Name", googleFirstName)
googleLastName = account?.familyName ?: ""
Log.i("Google Last Name", googleLastName)
googleEmail = account?.email ?: ""
Log.i("Google Email", googleEmail)
val googleIdToken: String = account?.idToken ?: ""
Log.i("Google ID Token", googleIdToken)
googleProfilePicURL = account?.photoUrl.toString()
Log.i("Google Profile Pic URL", googleProfilePicURL)
firebaseAuthWithGoogle(googleIdToken)
} catch (e: ApiException) {
// Sign in was unsuccessful
Log.e(
"failed code=", e.statusCode.toString()
)
}
}
private fun enablePersistence() {
// [START rtdb_enable_persistence]
Firebase.database.setPersistenceEnabled(true)
// [END rtdb_enable_persistence]
}
private fun firebaseAuthWithGoogle(idToken: String) {
val credential = GoogleAuthProvider.getCredential(idToken, null)
firebaseAuth.signInWithCredential(credential)
.addOnCompleteListener(this) { task ->
if (task.isSuccessful) {
// Sign in success, update UI with the signed-in user's information
Log.d(TAG, "signInWithCredential:success")
firebaseUserID = firebaseAuth.currentUser!!.uid
refUsers = FirebaseDatabase.getInstance().reference.child("Users").child(firebaseUserID)
refUsers.addListenerForSingleValueEvent(object : ValueEventListener {
override fun onDataChange(p0: DataSnapshot) {
if (p0.exists()) {
val user: Users? = p0.getValue(Users::class.java)
//Check if user exists in the database
if (user!!.getFirstName() != null) {
val intent = Intent(
this@WelcomeActivity,
IntroSplashScreen::class.java
)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(intent)
finish()
} else {
val usersHashMap = HashMap<String, Any>()
usersHashMap["uid"] = firebaseUserID
usersHashMap["firstname"] = googleFirstName
usersHashMap["surname"] = googleLastName
usersHashMap["profile"] = googleProfilePicURL
usersHashMap["primaryEmail"] = googleEmail
usersHashMap["search"] =
googleFirstName.toLowerCase(Locale.ROOT)
refUsers.updateChildren(usersHashMap)
.addOnCompleteListener {
if (task.isSuccessful) {
val intent = Intent(
this@WelcomeActivity,
NewProfileData::class.java
)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(intent)
finish()
}
}
}
}
}
override fun onCancelled(error: DatabaseError) {
TODO("Not yet implemented")
}
})
} else {
// If sign in fails, display a message to the user.
Log.w(TAG, "signInWithCredential:failure", task.exception)
// ...
}
// ...
}
}
private fun refreshIdToken() {
// Attempt to silently refresh the GoogleSignInAccount. If the GoogleSignInAccount
// already has a valid token this method may complete immediately.
//
// If the user has not previously signed in on this device or the sign-in has expired,
// this asynchronous branch will attempt to sign in the user silently and get a valid
// ID token. Cross-device single sign on will occur in this branch.
mGoogleSignInClient.silentSignIn()
.addOnCompleteListener(
this
) { task -> handleSignInResult(task) }
}
override fun onStart() {
super.onStart()
//Checks if the Google IDToken has expired, if yes it refreshes by SilentSign in and generates new Firebase Token
refreshIdToken()
//Checks if user is logged in to firebase
firebaseUser = FirebaseAuth.getInstance().currentUser
//If logged in then sends to MainActivity
if (firebaseUser != null) {
startActivity(IntroSplashScreen.getLaunchIntent(this))
finish()
}
}
override fun onResume() {
super.onResume()
refreshIdToken()
}
}
Комментарии:
1. firebase.google.com/docs/auth/android/google-signin
2. Привет, Мартин, спасибо за ваш ответ, я сначала вхожу в систему с помощью входа в Google, а затем пытаюсь войти в систему, используя тот же метод, что и в ссылке, которой вы поделились, но происходит вход в систему Google, Firebase имеет пользователя для аутентификации, но ни один пользователь не находится в базе данных реального времени в этой функции firebaseAuthWithGoogle (idToken:Строка)… adn экран не меняется…
Ответ №1:
Мой метод проверки того, существует ли пользователь, был неверным, поскольку процесс currect заключался в том, чтобы установить проверку на выходе Datasnapshot или нет. Если существует, то войдите в систему иначе зарегистрируйтесь.