위치정보를 기반으로 가까운 거리를 계산할 필요가 있어서 react-native에서 사용할 수 있는 라이브러리로 geofire, geofirestore, geofirex를 찾았다.
여러가지 고민을 하다가 stackoverflow에서도 자주 등장하는 geofirestore를 사용해보기로 했다.
그런데 계속 저장해도 검색이 안되었다. 결국 소스를 확인해보니 geofirestore에는 이번 프로젝트에 적용을 못하는 걸로 결정했다.
일단 원하는 구조가 고정되어 있고 firebase query를 덧불이기 어렵게 되어 있다.

  • 데이터구조
interface GeoDocument {
    g: string;
    l: GeoPoint;
    d: DocumentData;
  }
name description
g 라이브러리에서 만들어진 geohash
l GeoPoint를 기반으로 한 위치 데이터
d 데이터가 어디에 저장되어 있는 오브젝트

이렇게 구성되다 보니 document.location으로 구성된 데이터를 전체적으로 바꿔야 가능한 부분이었다.
고민하다가 결국 geofirex로 바꾸기로 했고, 이걸 알아내기까지 12시간정도 시간이 날아갔다.

이번 프로젝트에서는 두가지 조건을 처리해야 하는데 현재 위치에서 가까운 거리의 정보 검색과 다른 조건식과의 복합검색이다.

  1. 설치
yarn add geofirex rxjs

geofirex가 rxjs를 사용하기 때문에 같이 설치해야 한다.

  1. 현재 위치에서 가까운 거리의 정보 검색
import { firebase } from "@firebase/app";
import * as geofirex from "geofirex";

config = {
    apiKey: "",
    authDomain: "",
    databaseURL: "",
    projectId: "",
    storageBucket: "",
    messagingSenderId: ""
};
        
db = firebase.initializeApp(config);
geo = geofirex.init(firebase);

query = geocollection.within(
    geo.point(current_latitude, current_longitude),
    radius,
    "location"
);

geocollection = geo.collection(collection);
geofirex.get(query).then(snapshot => {
	snapshot.forEach(doc => {
        console.log(doc);
    });
});
  1. 다른 조건식과의 복합검색
    예를 들어 document에 같이 저장된 status가 true이고 age가 19보다 큰 경우를 같이 검색한다고 하면 geocollection에서 처리할 수 없고 CollectionReference를 사용해서 덧붙여야 한다.
    그리고 geofirex.init의 reference 부분은 {}를 사용하여 void function을 사용할 없기 때문에 function을 만들어 사용해야 한다.
    변경된 부분만 본다면 다음과 같다.
geo = geofirex.init(firebase,ref=>makeQuery(ref));

makeQuery(ref: geofirex.firestore.CollectionReference) {
    let query = ref.where("status","==",true).where("age",">",19);
    return query;
}

firebase 블로그에서 소개된 geofire나 geofirestore의 경우는 처음 구조를 잡는 단계라면 맞춰서 사용해볼 수 있겠지만 이미 구조가 잡혀서 진행중이라면 geofirex가 좋은 대안이 될리라 생각한다.

참고

geofire - GeoFire for JavaScript - Realtime location queries with Firebase
geofirestore - Location-based querying and filtering using Firebase's Firestore
geofirex - Geolocation Queries with Firestore & RxJS