iT邦幫忙

2023 iThome 鐵人賽

DAY 29
0
Mobile Development

Android studio使用過程與開發說明系列 第 29

Day29 - 使用Firebase與Android studio實現登入 (下篇)

  • 分享至 

  • xImage
  •  

功能


題外話,照片的人是我的朋友照片,因為覺得很好笑所以就把他抓進來做實驗。

登入成功的部分,不過這裡我只會教登入和建立帳號的部分。

套件安裝


1.先安裝套見到build.greadle(Module :app)

  • 安裝MultiDex
      //MultiDex
      implementation 'androidx.multidex:multidex:2.0.1'


在android裡的defaultConfig打上這行啟動它
https://ithelp.ithome.com.tw/upload/images/20231006/20161502Y5vgHJMsGS.png

   multiDexEnabled true
  • 安裝Rounded ImageView
  • 這是物件的套件,可以不使用沒關西,我頭象的部局是靠它做的
     //Rounded ImageView
     implementation 'com.makeramen:roundedimageview:2.3.0'


*在android{}裡打上這個新的
*這個套件可以幫助我們不用一直重寫findViewById()的部分

    buildFeatures{
        viewBinding true
    }




程式碼

  1. 創立兩個Empty Activity
    https://ithelp.ithome.com.tw/upload/images/20231009/20161502Ln6HbCWnRo.png
    取名為SingInActivity、SingUpActivity,畫面如下
    Notice:MainActivity是原本就有的,不理會。
    https://ithelp.ithome.com.tw/upload/images/20231009/20161502f99bXy4C3L.png
  2. 部局你的layout
    這裡只要確定有這些物件就可以了
    https://ithelp.ithome.com.tw/upload/images/20231009/20161502dqmecMr8sb.png

    3.創建一個資料夾(unilities),在裡面建立一個class 名叫做Constants(常數)
    https://ithelp.ithome.com.tw/upload/images/20231009/201615028GdPJXgUkr.png
    這些都是常用到的常數,有了這個就不需要一直去特別記住Key的部分。
    Constants
public class Constants {
    public static final String KEY_COLLECTION_USER = "user";
    public static final String KEY_NAME = "name";
    public static final String KEY_EMAIL = "email";
    public static final String KEY_PASSWORD = "password";
    public static final String KEY_PREFERENCE_NAME = "chatAppPreference";
    public static final String KEY_IS_SIGNED_IN = "isSignedIn";
    public static final String KEY_USER_ID = "userId";
    public static final String KEY_IMAGE = "image";
    public static final String KEY_FCM_TOKEN = "fcmToken";
    public static final String KEY_USER = "user";
    }


4. 寫程式碼
在程式碼裡如果看到progressBar的話話直接省略
SingInActivity

​
import androidx.appcompat.app.AppCompatActivity;
​
import android.content.Intent;
import android.os.Bundle;
​
​
import android.util.Patterns;
import android.view.View;
import android.widget.Toast;
​
import com.example.icecharapp.databinding.ActivitySinginBinding;
import com.example.icecharapp.ui.MainActivity;
import com.example.icecharapp.unilities.Constants;
import com.example.icecharapp.unilities.SharedPreferencesManager;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.FirebaseFirestore;
​
​
public class SingInActivity extends AppCompatActivity {
    //使用 ActivitySingInBinding 需要再build.gradle 的android{} 增新
    //buildFeatures{
    //    viewBinding true
    //}
    private ActivitySinginBinding binding;
    private SharedPreferencesManager sharedPreferencesManager;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivitySinginBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
        setListeners();
    }
​
    private void setListeners(){
        //轉跳頁面
        binding.textCreateNewAccount.setOnClickListener(view ->
                startActivity(new Intent(getApplicationContext(), SingUpActivity.class)));
        binding.buttonSignIn.setOnClickListener(view ->{
            SingIn();
        });
    }
    private void SingIn(){
        loading(true);
        FirebaseFirestore database = FirebaseFirestore.getInstance();
        database.collection(Constants.KEY_COLLECTION_USER)
                .whereEqualTo(Constants.KEY_EMAIL, binding.inputEmail.getText().toString())
                .whereEqualTo(Constants.KEY_PASSWORD, binding.inputPassword.getText().toString())
                .get()
                .addOnCompleteListener(task -> {
                    if(task.isSuccessful() && task.getResult() != null && task.getResult().getDocuments().size() > 0){
                        DocumentSnapshot documentSnapshot = task.getResult().getDocuments().get(0);
                        Intent intent = new Intent(getApplicationContext(), MainActivity.class);
                        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
                        startActivity(intent);
                    }
                    else{
                        loading(false);
                        showToast("Unable to sign in");
                    }
                });
    }
    private void loading(Boolean isLoading){
        if (isLoading){
            binding.buttonSignIn.setVisibility(View.INVISIBLE);
            binding.progressBar.setVisibility(View.VISIBLE);
        }
        else {
            binding.buttonSignIn.setVisibility(View.VISIBLE);
            binding.progressBar.setVisibility(View.INVISIBLE);
        }
    }
    private void showToast(String message){
        Toast.makeText(getApplicationContext(), message,Toast.LENGTH_SHORT).show();
    }
    private Boolean isValidSignInDetails(){
        if(binding.inputEmail.getText().toString().trim().isEmpty()){
            showToast("Enter email");
            return false;
        }
        else if(!Patterns.EMAIL_ADDRESS.matcher(binding.inputEmail.getText().toString()).matches()){
            showToast("Enter void email");
            return false;
        }
        else if(binding.inputPassword.getText().toString().trim().isEmpty()){
            showToast("Enter password");
            return false;
        }
        else {
            return true;
        }
    }
}


SingUpActivity

import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AppCompatActivity;
​
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Base64;
import android.util.Patterns;
import android.view.View;
import android.widget.Toast;
​
​
import com.example.icecharapp.databinding.ActivitySingUpBinding;
import com.example.icecharapp.ui.MainActivity;
import com.example.icecharapp.unilities.Constants;
import com.example.icecharapp.unilities.SharedPreferencesManager;
import com.google.firebase.firestore.FirebaseFirestore;
​
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.HashMap;
​
​
public class SingUpActivity extends AppCompatActivity {
    private ActivitySingUpBinding binding;
    private SharedPreferencesManager sharedPreferencesManager;
    private String encodeImage;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivitySingUpBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
        sharedPreferencesManager = new SharedPreferencesManager(getApplicationContext());
        setListeners();
    }
    private void setListeners(){
        //返回上一個頁面
        binding.textSignIn.setOnClickListener(v -> onBackPressed());
        //Sign Up
        binding.buttonSignUp.setOnClickListener(view -> {
            if (isValidSingUpDetails()){
                singUp();
            }
        });
        binding.layoutImage.setOnClickListener(view -> {
            Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
            intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
            pickImage.launch(intent);
        });
    }
​
    private void showToast(String message){
        Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
    }
    private void singUp(){
        loading(true);
        FirebaseFirestore database = FirebaseFirestore.getInstance();
        HashMap<String,Object> user = new HashMap<>();
        user.put(Constants.KEY_NAME, binding.inputName.getText().toString());
        user.put(Constants.KEY_EMAIL, binding.inputEmail.getText().toString());
        user.put(Constants.KEY_PASSWORD, binding.inputPassword.getText().toString());
        user.put(Constants.KEY_IMAGE, encodeImage);
        database.collection(Constants.KEY_COLLECTION_USER)
                .add(user)
                .addOnSuccessListener(documentReference -> {
                    loading(false);
                    Intent intent = new Intent(getApplicationContext(), MainActivity.class);
                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
                    startActivity(intent);
                })
                .addOnFailureListener(e -> {
                    loading(false);
                    showToast(e.getMessage());
                });
    }
    private String encodeImage(Bitmap bitmap){
        int previewWidth = 150;
        int previewHeight = bitmap.getHeight() * previewWidth / bitmap.getWidth();
        Bitmap previewBitmap = Bitmap.createScaledBitmap(bitmap, previewWidth, previewHeight,false);
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        previewBitmap.compress(Bitmap.CompressFormat.JPEG, 50, byteArrayOutputStream);
        byte[] bytes = byteArrayOutputStream.toByteArray();
        return Base64.encodeToString(bytes,Base64.DEFAULT);
    }
    private final ActivityResultLauncher<Intent> pickImage = registerForActivityResult(
            new ActivityResultContracts.StartActivityForResult(),
            result -> {
                if(result.getResultCode() == RESULT_OK){
                    if(result.getData() != null){
                        Uri imageUri = result.getData().getData();
                        try {
                            InputStream inputStream = getContentResolver().openInputStream(imageUri);
                            Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
                            binding.imageProfile.setImageBitmap(bitmap);
                            binding.textAddImage.setVisibility(View.GONE);
                            encodeImage = encodeImage(bitmap);
                        }
                        catch (FileNotFoundException e){
                            e.printStackTrace();
                        }
                    }
                }
            }
​
    );
    private Boolean isValidSingUpDetails(){
        if (encodeImage == null) {
            showToast("Select profile image");
            return false;
        }
        else if (binding.inputName.getText().toString().trim().isEmpty()){
            showToast("Enter name");
            return false;
        }
        else if (binding.inputEmail.getText().toString().trim().isEmpty()){
            showToast("Enter Email");
            return false;
        }
        else if (!Patterns.EMAIL_ADDRESS.matcher(binding.inputEmail.getText().toString()).matches()){
            showToast("Enter valid Email");
            //檢查一個字串是否為有效的電子郵件地址
            return false;
        }
        else if (binding.inputPassword.getText().toString().trim().isEmpty()){
            showToast("Enter password");
            return false;
        }
        else if (binding.inputConfirmPassword.getText().toString().trim().isEmpty()){
            showToast("Enter Confirm Password");
            return false;
        }
        else if (!binding.inputPassword.getText().toString().equals(binding.inputConfirmPassword.getText().toString())){
            showToast("Password & confirm password must be same");
            return false;
        }
        else {
            return true;
        }
    }
    private void loading(Boolean isLoading){
        if(isLoading){
            binding.buttonSignUp.setVisibility(View.INVISIBLE);
            binding.progressBar.setVisibility(View.VISIBLE);
        }
        else{
            binding.buttonSignUp.setVisibility(View.VISIBLE);
            binding.progressBar.setVisibility(View.INVISIBLE);
        }
    }
}


完成之後就可以去建立一個創號試試,然後在你的Firebase的Firestore部分可意看到資料有增新。
只需要看user的部分就好了,其他的Conversation、chat是後續的功能,這裡我不做教學用。
https://ithelp.ithome.com.tw/upload/images/20231009/20161502HQsxPjBTLF.png


上一篇
Day28 - 使用Firebase與Android studio實現登入(上篇)
下一篇
Day30 - 完賽結言
系列文
Android studio使用過程與開發說明30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言