마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

안드로이드 파이어베이스 리얼타임 데이터 가져오기

0 추천

안녕하세요 코딩뉴비 입니다. 안드로이드로 앱개발 중 어찌저찌 회원가입 기능은 구현했는데 로그인 기능을 구현하고자 리얼타임 에서 아이디와 비밀번호에 맞는 데이터가 있는지 확인하는 코드를 구현하고 싶은데.. 너무 어렵고 정보가 없습니다.첫번째 사진은 리얼타임에 저장된 데이터 형식입니다.어떻게 하면 로그인 화면에서 입력한 이메일과 비밀번호를 가져와 리얼타임에 있는 데이터와 비교하여 로그인 기능을 만들수 있을까요..?

코딩뉴비 (310 포인트) 님이 2022년 10월 7일 질문

1개의 답변

+1 추천
 
채택된 답변

Firebase SDK를 사용하신다고 가정할게요. 먼저 개발자 페이지에 가셔서 어떻게 데이터를 읽고 쓰는지 읽어 보세요.

https://firebase.google.com/docs/database/android/read-and-write

Read data once(https://firebase.google.com/docs/database/android/read-and-write#read_data_once) 섹션에 있는 샘플을 참조하시면 구현이 가능할 것으로 보이네요.

아래와 같이 SDK에서 제공하는 기본 기능을 이용해서 구현해 보았습니다.

사용자 정보를 담는 POJO 클래스입니다.

public class User {
    private String signID;
    private String signmail;
    private String signName;

    public User() {
    }

    public String getSignID() {
        return signID;
    }

    public void setSignID(String signID) {
        this.signID = signID;
    }

    public String getSignmail() {
        return signmail;
    }

    public void setSignmail(String signmail) {
        this.signmail = signmail;
    }

    public String getSignName() {
        return signName;
    }

    public void setSignName(String signName) {
        this.signName = signName;
    }

    @Override
    public String toString() {
        return "Member{" +
                "signID='" + signID + '\'' +
                ", signmail='" + signmail + '\'' +
                ", signName='" + signName + '\'' +
                '}';
    }
}

 

로그인처리를 담당하는 Repsoitory클래스입니다.

public class UserRepository {

    interface Listener {
        void onLoginSuccess(User user);

        void onLoginFailure(DatabaseError error);
    }

    private static final String TABLE_NAME = "member";
    private static final String ID_FIELD_NAME = "signID";
    private static final String PASSWORD_FIELD_NAME = "signPw";

    private final DatabaseReference dbRef;
    private Listener listener;

    public UserRepository() {
        this.dbRef = FirebaseDatabase.getInstance().getReference();
    }

    public void setListener(Listener listener) {
        this.listener = listener;
    }

    public void login(String userId, String password) {
        dbRef.child(TABLE_NAME).addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                handleMemberFetched(dataSnapshot.getChildren(), userId, password);
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                if (listener != null) listener.onLoginFailure(databaseError);
            }
        });
    }

    private void handleMemberFetched(Iterable<DataSnapshot> snapshots, String userId, String password) {
        User loggeedInUser = null;
        for (DataSnapshot snapshot : snapshots) {
            String signID = snapshot.child(ID_FIELD_NAME).getValue() + "";
            String signPw = snapshot.child(PASSWORD_FIELD_NAME).getValue() + "";

            if (signID.equals(userId) && signPw.equals(password)) {
                loggeedInUser = snapshot.getValue(User.class);
                break;
            }
        }

        if (loggeedInUser == null) {
            if (listener != null) listener.onLoginFailure(null);
            return;
        }

        if (listener != null) listener.onLoginSuccess(loggeedInUser);
    }
}

 

액티비티입니다.

public class MainActivity extends AppCompatActivity implements UserRepository.Listener {

    private UserRepository userRepository;

    private EditText userIdEdit, passwordEdit;
    private Button loginButton;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        injectDependencies();
        bindViews();
    }

    @Override
    protected void onStart() {
        super.onStart();
        userRepository.setListener(this);
    }

    @Override
    protected void onStop() {
        super.onStop();
        userRepository.setListener(null);
    }

    private void injectDependencies() {
        userRepository = new UserRepository();
    }

    private void bindViews() {
        userIdEdit = findViewById(R.id.userIdEdit);
        passwordEdit = findViewById(R.id.passwordEdit);
        loginButton = findViewById(R.id.loginButton);
        loginButton.setOnClickListener(v -> {
            submitLogin();
        });
    }

    private void submitLogin() {
        loginButton.setEnabled(false);
        userRepository.login(userIdEdit.getText().toString(), passwordEdit.getText().toString());
    }

    @Override
    public void onLoginSuccess(User user) {
         // 로그인 성공 처리
    }

    @Override
    public void onLoginFailure(DatabaseError error) {
        if (error != null) {
            showLoginError(R.string.database_error_message);
            return;
        }

        showLoginError(R.string.login_failure_message);
    }

    private void showLoginError(int resId) {
        Toast.makeText(this, resId, Toast.LENGTH_SHORT).show();
        loginButton.setEnabled(true);
    }
}

 

 그리고 한가지 제안을 드리자면 Firebase 에 member 를 저장할 때 노드의 key("NdmFH4jvjxry~"에 해당하는 값)를 자동생성되는 값으로 하지 말고 signID로 하시면,  사용자를 찾기위해 데이터를 모두 읽어와야 하는 비횰율적인 방법 대신 아래처럼 한번에 읽어올 수 있을 것 같습니다.

dbRef.child(TABLE_NAME).child(userId).get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
    @Override
    public void onComplete(@NonNull Task<DataSnapshot> task) {
        if (!task.isSuccessful()) {
            Log.e("firebase", "Error getting data", task.getException());
        }
        else {
            Log.d("firebase", String.valueOf(task.getResult().getValue()));
        }
    }
});

 

spark (227,930 포인트) 님이 2022년 10월 8일 답변
코딩뉴비님이 2022년 10월 24일 채택됨
제 예제에서는 signId와 비교를 했는데, 이부분을 이메일과 비교하는 걸로 바꾸세요.
그리고  FirebaseUI를 사용하시면 회원등록, 로그인 모두 아주 갖편하게 처리됩니다.
감사합니다 ㅠㅠ  덕분에 도움 많이 됬습니다!
...