Firebase AuthenticationをAndroidアプリケーションで使用しています。アプリケーションにサインインするオプションとしてGoogleアカウント認証を使用しています。
ユーザーが初めてアプリケーションにサインインしたかどうかを知るにはどうすればよいですか?
ユーザーが初めてログインしたかどうかを確認するには、_OnCompleteListener.onComplete
_コールバックでAdditionalUserInfo.isNewUser()
メソッドを呼び出すだけです。
以下のコード例では、必ずnullを確認してください。
_OnCompleteListener<AuthResult> completeListener = new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
boolean isNew = task.getResult().getAdditionalUserInfo().isNewUser();
Log.d("MyTAG", "onComplete: " + (isNew ? "new user" : "old user"));
}
}
};
_
詳細なリファレンスについてはドキュメントを確認してください AdditionalUserInfo
Firebase-ui docs から、次のように、作成時のタイムスタンプに対して最後のサインインタイムスタンプを確認できます。
FirebaseUserMetadata metadata = auth.getCurrentUser().getMetadata();
if (metadata.getCreationTimestamp() == metadata.getLastSignInTimestamp()) {
// The user is new, show them a fancy intro screen!
} else {
// This is an existing user, show them a welcome back screen.
}
Firebase auth(16.0.1)の新しいバージョンによると、AuthResultクラスには、trueまたはfalseのメンバー関数があります(ユーザーは新規です)。 「資格情報」がスコープで定義されていると仮定します(Google資格情報です)。以下に例を示します。 `
private FirebaseAuth mAuth;
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id))
.requestEmail()
.build();
mAuth = FirebaseAuth.getInstance();
Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
GoogleSignInAccount acct = task.getResult(ApiException.class);
AuthCredential credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null);
mAuth.signInWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
Log.d(TAG, "linkWithCredential:success");
boolean newuser = task.getResult().getAdditionalUserInfo().isNewUser();
if(newuser){
//Do Stuffs for new user
}else{
//Continue with Sign up
}
} else {
Toast.makeText(MyClass.this, "Authentication failed.",
Toast.LENGTH_SHORT).show();
}
});
firebaseのおかげで:)
バージョン11.6.0以降では、AdditionalUserInfo.isNewUser()
を使用できます
https://firebase.google.com/docs/reference/Android/com/google/firebase/auth/AdditionalUserInfo
Firebase AuthとFirestoreを併用する場合の解決策
Firestoreデータベースのルートアーキテクチャは次のようになります
Firebase Auth currentUser.uid
を使用して、各ユーザーのルートドキュメントを作成します。最初にユーザーが作成されたらすぐにregistered_at
というフィールドをルートドキュメントに追加し、ユースケースに応じて特定のコレクションをルートドキュメントに追加します。
ログインまたはサインインするときに、registered_at
フィールドを持つドキュメントが既に存在するかどうかを確認できます。まだ存在しない場合は、ユーザーを新しいユーザーとして扱うことができます(ユーザーが後でregistered_at
フィールドを削除または変更できない場合)
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.firestore.DocumentReference
import com.google.firebase.firestore.FirebaseFirestore
fun rootDocument(): DocumentReference? = rootPath()?.let {
return fireStore().document(it)
}
fun rootPath(): String? {
val loggedInUser = loggedInUser()
if (loggedInUser != null) {
return "users/${loggedInUser.uid}"
}
return null
}
fun fireStore() = FirebaseFirestore.getInstance()
fun createWriteBatch() = fireStore().batch()
fun loggedInUser() = fireAuth().currentUser
fun fireAuth(): FirebaseAuth = FirebaseAuth.getInstance()
fun afterSignIn() {
val rootDocument = rootDocument()
?: throw IllegalStateException("root document not found")
rootDocument.get().addOnCompleteListener {
val isNewUser = it.result.exists().not()
if (isNewUser) {
val batch = createWriteBatch()
batch.set(rootDocument, HashMap<Any, Any>().apply {
put("registered_at", System.currentTimeMillis())
})
batch.commit().addOnCompleteListener {
println("this is a new user")
}
} else {
println("this is not a new user")
}
}
}
これはあなたを助け、それを試すかもしれません:
最も正しい方法(認証ユーザーテーブルに新しいフィールドを追加できない場合)はユーザーの新しいパスを作成し、そこに情報を保存することであることに完全に同意しますが、ログイン後に追加のリクエストを行いたくありませんこのチェックを行います(私はFirestoreを使用しており、requests = money)。
UserNameのプロンプトに対してこの最初のログインチェックを行う必要がありました(表示名はFacebook/Googleから取得され、最初のログインの場合はオーバーライドするオプションを指定したかったため)。最終的には、photoURLプロパティをフラグとして使用して、初めてかどうかを判断していました。これは理想的ではありませんが、リクエストを保存したい人は回避策としてこれを使用できます。 Firebaseにとってはそれほど大きな問題ではありませんが、Firestoreにとっては計画にとってよりコストがかかります