[Android] Firestore 규칙

노아카프카·2022년 2월 3일
0

현재 간단하게 진행중인 프로젝트에서 Firebase의 FireStore를 사용하게 되었다.
다른 사람이 하던 프로젝트를 넘겨받아서 RealtimeDatabase 와 FireStore의 차이점을 제대로 모른채로 작업했다가 이제서야 정리한다.


RealtimeDatabase 와 Firestore의 차이점

  1. Data Model :
    (RealtimeDatabase) JSON Tree -> 정규화 불편함.
    (FireStore) Collection > Document(key - value)

  2. Query
    (RealtimeDatabase) 정렬 및 필터링은 가능. But, 동시 필터링 X / 특정 depth의 데이터를 반환할 때, 하위 depth 전체 반환 -> 성능 저하 가능성 O
    (FireStore) 정렬 및 필터링 조건문 동시 사용 가능 / 특정 컬렉션이나 컬렉션이 가지고 있는 문서만 반환

  3. Extension
    (RealtimeDatabase) 단일db 동시연결 약 10만개, 초당 쓰기 약 1천 회 -> 확장하려면 여러 db로 샤딩 필요.
    (FireStore) 샤딩X, 확장이 자동으로 수행됨. 최대 확장한도는 동시 연결수 약 100만개, 초당 쓰기 약 1만회 -> 개별 문서 or 색인의 쓰기 속도에는 제한이 있음(문서 : 초당 1개, 색인 : 초당 500회)


Firestore 보안 규칙 - Security Rules

문제가 생겼던 Firestore 규칙에 대해서 알아보자.
firestore에는 document에 대한 접근 및 CRUD 처리에 관한 권한을 설정할 수 있는 규칙이라는게 있음.

어느날, 메일 하나가 도착했다.

!보안 규칙에서 다음 문제가 감지되었습니다.

  • 모든 사용자가 전체 데이터베이스를 읽을 수 있습니다.
  • 모든 사용자가 전체 데이터베이스에 쓸 수 있습니다.

문제는 규칙에 있었다.
기존에 설정되어있던 규칙은 아래와 같았다.
원래 작업하던 사람이 allow read, write: if false; 였던 규칙이 안되니까 true로만 바꿔버린거같았다.

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if true;
    }
  }
}

이 규칙에 따르면 이 Firestore Project에 등록된 앱을 사용하는 모든 사용자가 DB 내의 모든 Collection 및 문서에 CRUD 작업을 할 수 있다.
그렇기 때문에 경고 메세지가 왔고, 사용자에 따라 접근 권한을 설정해줘야 했다.


인증 - Authentication

보안 규칙에서 특정 사용자에게 권한을 주기 위해서는, 특정 사용자를 구분할 수 있는 인증 절차가 필요하다.
이 작업을 위한 준비물은 세 가지.

  • 사용자 등록
  • 규칙 수정
  • 등록된 사용자로 인증 요청
  1. 먼저 사용자 등록의 경우, Client에서 요청을 할 수도 있지만( createUserWithEmailAndPassword 함수 사용 )
    나의 경우에는 단 하나의 사용자(팀 공용 계정)만 필요하기 때문에, 수동으로 Firebase 웹(Project > Build > Authentication)에서 이메일과 비밀번호를 등록했다.

  2. 그리고 나서 규칙을 아래와 같이 수정했다.

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if request.auth != null;
    }
  }
}

수정했다고 하기도 민망할 정도..
"request.auth 가 있으면" read, write 권한을 주도록 수정했다.
request.auth 는 Firebase Auth를 사용하여 인증되었다고 가정하는 사용자 정보를 포함한다.

  1. 마지막으로 안드로이드 소스에서 인증 요청 및 인증값을 계속 유지하도록 하는 코드를 삽입했다.
fun signIn(){
        auth.signInWithEmailAndPassword("이메일", "비밀번호")
            .addOnCompleteListener(this) { task ->
                if (task.isSuccessful) {
                    // Sign in success, update UI with the signed-in user's information
                    val user = auth.currentUser
                    Toast.makeText(baseContext, "Authentication succeed : " + user!!.email.toString() ,
                        Toast.LENGTH_SHORT).show()
                } else {
                    // If sign in fails, display a message to the user.
                    Toast.makeText(baseContext, "Authentication failed.",
                        Toast.LENGTH_SHORT).show()
                }
            }
    }

0개의 댓글