Аутентификация на базе Android Firebase — Вход через Google на Kotlin

Firebase Authentication предоставляет серверные службы для простого использования SDK и встроенных библиотек пользовательского интерфейса для аутентификации пользователя в приложении. Большинству приложений требуется идентификация пользователя, и, узнав их статус, приложение надежно сохраняет данные пользователя в облаке. Оно направлено на создание безопасной системы аутентификации.

Используя Kotlin Android Firebase Authentication, мы будем аутентифицировать вход в Google, Facebook, GitHub, Twitter, и подключать Google reCaptcha.

В этом руководстве мы интегрируем функцию аутентификации Firebase для входа в Google в наше приложение для Android с помощью API Google и Firebase в Котлин.

Действия по созданию и настройке приложения Android в учетной записи Google Firebase

1. Создайте учетную запись разработчика Firebase на странице https://firebase.google.com/ и нажмите «GO TO CONSOLE».

2. Нажмите «Добавить проект».

3. Заполните имя проекта и выберите местоположение аналитики, местоположение облачного хранилища Firestore, примите условия контроллера и нажмите «Создать проект».

Создать проект

4. Когда ваш новый проект будет успешно готов, нажмите «Продолжить».

Аутентификация Android Firebase — вход через Google

5. Выберите SDK платформы «Android».

Выбор SDK платформы «Android»

6. Зарегистрируйте свое приложение в Firebase, предоставив необходимую информацию о приложении, и нажмите «Зарегистрировать приложение».

Мы можем получить ключ SHA-1 сертификата приложения, выполнив следующие действия:

  1. Откройте проект Android.
  2. Откройте вкладку Gradle на правой боковой панели.
  3. Дважды щелкните «signingReport».
  4. Мы найдем ключ SHA-1 нашего приложения в «Gradle Console».

Получение ключа SHA-1 сертификата приложения

7. Теперь загрузите файл «google-services.json», чтобы интегрировать его в приложение Android, и нажмите «Далее».

Загрузка файла «google-services.json»

8. Добавьте зависимости Firebase SDK в файлы .gradle вашего приложения, нажмите «Синхронизировать сейчас» в среде IDE и нажмите «Далее».

Синхронизировать сейчас

build.gradle(Project)

 
dependencies { 
    classpath 'com.android.tools.build:gradle:3.0.1' 
    classpath 'com.google.gms:google-services:4.0.1' 
 
    // NOTE: Do not place your application dependencies here; they belong 
    // in the individual module build.gradle files 
} 

build.gradle(Module)

 
dependencies { 
    implementation fileTree(dir: 'libs', include: ['*.jar']) 
    implementation 'com.android.support:appcompat-v7:27.1.1' 
    implementation 'com.android.support.constraint:constraint-layout:1.1.3' 
    testImplementation 'junit:junit:4.12' 
    androidTestImplementation 'com.android.support.test:runner:1.0.2' 
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 
    implementation 'com.google.firebase:firebase-auth:16.0.3' 
    implementation 'com.google.firebase:firebase-core:16.0.3' 
    implementation 'com.google.android.gms:play-services-auth:16.0.0' 
    implementation 'com.github.bumptech.glide:glide:3.7.0' 
} 
apply plugin: 'com.google.gms.google-services' 

AndroidManifest.xml

Добавьте разрешение Интернета в файл AndroidManifest.xml для доступа к сетевому подключению.

 <uses-permission android:name="android.permission.INTERNET" /> 
 

9. Запустите приложение, чтобы проверить конфигурацию установки. Если все в порядке, оно отобразит сообщение об успешном выполнении, а затем нажмите «Продолжить в консоли».

Продолжить в консоли

10. На странице консоли выберите «Аутентификация» -> «Метод входа» -> «Google» -> «Включить» и нажмите «Сохранить».

Аутентификация

Пример аутентификации Android Firebase с помощью входа в Google

В этом примере мы интегрируем аутентификацию Firebase с входом Google в наше приложение для Android. Как только пользователь успешно войдет в систему через Google Sign-In, мы аутентифицируем его с помощью Firebase Authentication, а затем перенаправим пользователя к следующему действию(ProfileActivity) и отобразим его данные.

Нам нужно вставить загруженный файл google-services.json в каталог приложения нашего проекта Android.

Activity_main.xml

Добавьте следующий код в файл activity_main.xml. В этом примере мы реализуем настраиваемую кнопку входа в Google.

<?xml version="1.0" encoding="utf-8"?>  
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    xmlns:app="http://schemas.android.com/apk/res-auto"  
    xmlns:tools="http://schemas.android.com/tools"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent"  
    tools:context="example.javatpoint.com.firebasegooglelogin.MainActivity">  
  
    <TextView  
        android:id="@+id/textView"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:layout_marginLeft="20dp"  
        android:layout_marginRight="20dp"  
        android:textSize="20dp"  
        android:text="This is main activity, sign in to move next activity." />  
  
    <com.google.android.gms.common.SignInButton  
        android:layout_width="match_parent"  
        android:layout_height="wrap_content"  
        android:id="@+id/sign_in_button"  
        android:layout_marginLeft="20dp"  
        android:layout_marginRight="20dp"  
        android:layout_alignParentBottom="true"  
        android:layout_marginBottom="20dp">  
  
    </com.google.android.gms.common.SignInButton>  
  
  
</RelativeLayout>

string.xml

Добавьте идентификатор веб-клиента в файл string.xml. Даже вы можете использовать идентификатор веб-клиента Google по умолчанию в программе.

<resources>  
    <string name="app_name">Firebase Google Login</string>  
    <string name="web_client_id">xxxxxxxx..place your web client id here</string>  
</resources> 

MainActivity.java

Добавьте следующий код в класс MainActivity.java. Функциональность классов и методов, используемых в классе MainActivity.java, представлена ниже:

  1. Новый FirebaseAuth.AuthStateListener(){} используется в качестве прослушивателя аутентификации, чтобы проверить, вошел ли пользователь в систему или нет. Если пользователи успешно вошли в систему, мы размещаем другую логику firebase.
  2. Новый метод GoogleSignInOptions.Builder() настраивает вход в Google для получения данных пользователя с помощью параметра requestEmail.
  3. Нажав кнопку «Вход», он вызывает Auth.GoogleSignInApi.getSignInIntent(googleApiClient) и запускает намерение с помощью startActivityForResult().
  4. В onActivityResult() мы получаем результат запроса на вход в Google.
  5. Если handleSignInResult(result) возвращает true, мы получаем аутентификацию Google с помощью idToken.
  6. Вызов firebaseAuthWithGoogle(credential) для аутентификации Firebase с Google.

Если аутентификация Firebase прошла успешно, мы перенаправляем пользователя к следующему действию(ProfileActivity.java).

 
package example.javatpoint.com.firebasegooglelogin; 
 
import android.content.Intent; 
import android.support.annotation.NonNull; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.View; 
import android.widget.Toast; 
 
import com.google.android.gms.auth.api.Auth; 
import com.google.android.gms.auth.api.signin.GoogleSignInAccount; 
import com.google.android.gms.auth.api.signin.GoogleSignInOptions; 
import com.google.android.gms.auth.api.signin.GoogleSignInResult; 
import com.google.android.gms.common.ConnectionResult; 
import com.google.android.gms.common.SignInButton; 
import com.google.android.gms.common.api.GoogleApiClient; 
import com.google.android.gms.tasks.OnCompleteListener; 
import com.google.android.gms.tasks.Task; 
import com.google.firebase.auth.AuthCredential; 
import com.google.firebase.auth.AuthResult; 
import com.google.firebase.auth.FirebaseAuth; 
import com.google.firebase.auth.FirebaseUser; 
import com.google.firebase.auth.GoogleAuthProvider; 
 
public class MainActivity extends AppCompatActivity implements GoogleApiClient.OnConnectionFailedListener { 
 
    private static final String TAG = "MainActivity"; 
    private SignInButton signInButton; 
    private GoogleApiClient googleApiClient; 
    private static final int RC_SIGN_IN = 1; 
    String name, email; 
    String idToken; 
    private FirebaseAuth firebaseAuth; 
    private FirebaseAuth.AuthStateListener authStateListener; 
 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.activity_main); 
 
        firebaseAuth = com.google.firebase.auth.FirebaseAuth.getInstance(); 
        //this is where we start the Auth state Listener to listen for whether the user is signed in or not 
        authStateListener = new FirebaseAuth.AuthStateListener(){ 
            @Override 
            public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) { 
                // Get signedIn user 
                FirebaseUser user = firebaseAuth.getCurrentUser(); 
 
                //if user is signed in, we call a helper method to save the user details to Firebase 
                if(user != null) { 
                    // User is signed in 
                    // you could place other firebase code 
                    //logic to save the user details to Firebase 
                    Log.d(TAG, "onAuthStateChanged:signed_in:" + user.getUid()); 
                } else { 
                    // User is signed out 
                    Log.d(TAG, "onAuthStateChanged:signed_out"); 
                } 
            } 
        }; 
 
        GoogleSignInOptions gso =  new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) 
                .requestIdToken(getString(R.string.web_client_id))//you can also use R.string.default_web_client_id 
                .requestEmail() 
                .build(); 
        googleApiClient=new GoogleApiClient.Builder(this) 
                .enableAutoManage(this,this) 
                .addApi(Auth.GOOGLE_SIGN_IN_API,gso) 
                .build(); 
 
        signInButton = findViewById(R.id.sign_in_button); 
        signInButton.setOnClickListener(new View.OnClickListener() { 
            @Override 
            public void onClick(View view) { 
                Intent intent = Auth.GoogleSignInApi.getSignInIntent(googleApiClient); 
                startActivityForResult(intent,RC_SIGN_IN); 
            } 
        }); 
    } 
 
    @Override 
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { 
 
    } 
 
    @Override 
    protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
        super.onActivityResult(requestCode, resultCode, data); 
        if(requestCode==RC_SIGN_IN){ 
            GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data); 
            handleSignInResult(result); 
        } 
    } 
 
    private void handleSignInResult(GoogleSignInResult result){ 
        if(result.isSuccess()){ 
            GoogleSignInAccount account = result.getSignInAccount(); 
            idToken = account.getIdToken(); 
            name = account.getDisplayName(); 
            email = account.getEmail(); 
            // you can store user data to SharedPreference 
            AuthCredential credential = GoogleAuthProvider.getCredential(idToken, null); 
            firebaseAuthWithGoogle(credential);  
        }else{ 
            // Google Sign In failed, update UI appropriately 
            Log.e(TAG, "Login Unsuccessful. "+result); 
            Toast.makeText(this, "Login Unsuccessful", Toast.LENGTH_SHORT).show(); 
        } 
    } 
    private void firebaseAuthWithGoogle(AuthCredential credential){ 
 
        firebaseAuth.signInWithCredential(credential) 
                .addOnCompleteListener(this, new OnCompleteListener() { 
                    @Override 
                    public void onComplete(@NonNull Task task) { 
                        Log.d(TAG, "signInWithCredential:onComplete:" + task.isSuccessful()); 
                        if(task.isSuccessful()){ 
                            Toast.makeText(MainActivity.this, "Login successful", Toast.LENGTH_SHORT).show(); 
                            gotoProfile(); 
                        }else{ 
                            Log.w(TAG, "signInWithCredential" + task.getException().getMessage()); 
                            task.getException().printStackTrace(); 
                            Toast.makeText(MainActivity.this, "Authentication failed.", 
                                    Toast.LENGTH_SHORT).show(); 
                        } 
 
                    } 
                }); 
    } 
 
 
 
 
    private void gotoProfile(){ 
        Intent intent = new Intent(MainActivity.this, ProfileActivity.class); 
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); 
        startActivity(intent); 
        finish(); 
    } 
    @Override 
    protected void onStart() { 
        super.onStart(); 
        if(authStateListener != null){ 
            FirebaseAuth.getInstance().signOut(); 
        } 
        firebaseAuth.addAuthStateListener(authStateListener); 
    } 
 
    @Override 
    protected void onStop() { 
        super.onStop(); 
        if(authStateListener != null){ 
            firebaseAuth.removeAuthStateListener(authStateListener); 
        } 
    } 
 
} 

profile_activity.xml

Добавьте следующий код в файл profile_activity.xml. ImageView используется для отображения изображения профиля пользователя, TextView — для имени, идентификатора электронной почты и кнопки для выхода из системы.

<?xml version="1.0" encoding="utf-8"?>  
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    xmlns:app="http://schemas.android.com/apk/res-auto"  
    xmlns:tools="http://schemas.android.com/tools"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent"  
    tools:context="example.javatpoint.com.firebasegooglelogin.ProfileActivity">  
  
  
        <LinearLayout  
            android:layout_width="match_parent"  
            android:layout_height="match_parent"  
            android:gravity="center"  
            android:orientation="vertical">  
            <ImageView  
                android:layout_width="80dp"  
                android:layout_height="80dp"  
                android:id="@+id/profileImage"  
                />  
            <TextView  
                android:layout_width="wrap_content"  
                android:layout_height="wrap_content"  
                android:id="@+id/name"  
                android:text="name"  
                android:textSize="20dp"  
                android:layout_marginTop="20dp"/>  
            <TextView  
                android:layout_width="wrap_content"  
                android:layout_height="wrap_content"  
                android:id="@+id/email"  
                android:textSize="20dp"  
                android:text="email"  
                android:layout_marginTop="20dp"/>  
            <TextView  
                android:layout_width="wrap_content"  
                android:layout_height="wrap_content"  
                android:id="@+id/userId"  
                android:textSize="20dp"  
                android:text="id"  
                android:layout_marginTop="20dp"/>  
            <Button  
                android:layout_width="wrap_content"  
                android:layout_height="wrap_content"  
                android:id="@+id/logoutBtn"  
                android:text="Logout"  
                android:layout_marginTop="30dp"/>  
        </LinearLayout>  
</RelativeLayout>

ProfileActivity.java

В этом классе ProfileActivity.java мы получаем информацию о пользователе и отображаем ее. Класс GoogleSignInResult реализует интерфейс Result, который представляет окончательный результат вызова метода API сервисов Google Play.

Класс GoogleSignInAccount хранит необходимую информацию о пользователе.

 
package example.javatpoint.com.firebasegooglelogin; 
 
import android.content.Intent; 
import android.support.annotation.NonNull; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.Button; 
import android.widget.ImageView; 
import android.widget.TextView; 
import android.widget.Toast; 
 
import com.bumptech.glide.Glide; 
import com.google.android.gms.auth.api.Auth; 
import com.google.android.gms.auth.api.signin.GoogleSignInAccount; 
import com.google.android.gms.auth.api.signin.GoogleSignInOptions; 
import com.google.android.gms.auth.api.signin.GoogleSignInResult; 
import com.google.android.gms.common.ConnectionResult; 
import com.google.android.gms.common.api.GoogleApiClient; 
import com.google.android.gms.common.api.OptionalPendingResult; 
import com.google.android.gms.common.api.ResultCallback; 
import com.google.android.gms.common.api.Status; 
import com.google.firebase.auth.FirebaseAuth; 
 
public class ProfileActivity extends AppCompatActivity implements GoogleApiClient.OnConnectionFailedListener { 
    Button logoutBtn; 
    TextView userName,userEmail,userId; 
    ImageView profileImage; 
    private GoogleApiClient googleApiClient; 
    private GoogleSignInOptions gso; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.activity_profile); 
 
        logoutBtn = findViewById(R.id.logoutBtn); 
        userName = findViewById(R.id.name); 
        userEmail = findViewById(R.id.email); 
        userId = findViewById(R.id.userId); 
        profileImage = findViewById(R.id.profileImage); 
 
        gso =  new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) 
                .requestEmail() 
                .build(); 
 
        googleApiClient=new GoogleApiClient.Builder(this) 
                .enableAutoManage(this,this) 
                .addApi(Auth.GOOGLE_SIGN_IN_API,gso) 
                .build(); 
 
 
        logoutBtn.setOnClickListener(new View.OnClickListener() { 
            @Override 
            public void onClick(View view) { 
                FirebaseAuth.getInstance().signOut(); 
                Auth.GoogleSignInApi.signOut(googleApiClient).setResultCallback( 
                        new ResultCallback() { 
                            @Override 
                            public void onResult(Status status) { 
                                if(status.isSuccess()){ 
                                    gotoMainActivity(); 
                                }else{ 
                                    Toast.makeText(getApplicationContext(),"Session not close",Toast.LENGTH_LONG).show(); 
                                } 
                            } 
                        }); 
            } 
        }); 
    } 
 
    @Override 
    protected void onStart() { 
        super.onStart(); 
        OptionalPendingResult opr= Auth.GoogleSignInApi.silentSignIn(googleApiClient); 
        if(opr.isDone()){ 
            GoogleSignInResult result=opr.get(); 
            handleSignInResult(result); 
        }else{ 
            opr.setResultCallback(new ResultCallback() { 
                @Override 
                public void onResult(@NonNull GoogleSignInResult googleSignInResult) { 
                    handleSignInResult(googleSignInResult); 
                } 
            }); 
        } 
    } 
    private void handleSignInResult(GoogleSignInResult result){ 
        if(result.isSuccess()){ 
            GoogleSignInAccount account=result.getSignInAccount(); 
            userName.setText(account.getDisplayName()); 
            userEmail.setText(account.getEmail()); 
            userId.setText(account.getId()); 
            try{ 
                Glide.with(this).load(account.getPhotoUrl()).into(profileImage); 
            }catch(NullPointerException e){ 
                Toast.makeText(getApplicationContext(),"image not found",Toast.LENGTH_LONG).show(); 
            } 
 
        }else{ 
            gotoMainActivity(); 
        } 
    } 
    private void gotoMainActivity(){ 
        Intent intent=new Intent(this,MainActivity.class); 
        startActivity(intent); 
    } 
    @Override 
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { 
 
    } 
} 

Выход:

Вывод 1
Вывод 2

Вывод 3
Выбор аккаунта

В следующем разделе разберем как добавить Google reCAPTCHA в приложении для Android.

Оцените статью