목표
내 앱이 현재 최신 버전인지 확인하고, 최신 버전이 아니라면 업데이트를 하도록 유도하는 다이얼로그를 화면에 띄운다. 최신 버전이 아니여도 호환이 되는 상태기 때문에 업데이트를 강제하지는 않는다.
만약 앱이 최신버전이 아니고, 최신 버전과 호환되지 않는 상태라면 ( 최소 앱 버전보다 낮다면) 업데이트를 강제하고 앱 사용을 중단시킨다.
해결 방법
사용중인 유저의 앱의 버전은 반드시 최소로 요구되는 버전보다 크거나 같아야 하고 최신 버전 이하여야 한다.
minimumAppVersion <= currentAppVersion <= LatestAppVersion
앱에서 업데이트를 요구하기 위해서는 먼저 최소 버전(minAppVersion)과 최신 버전(latestAppVersion)을 알아야 하는데, 이 작업이 생각보다 쉽지 않다. IOS 같은 경우에는 url을 통하여 버전을 가져올 수 있다.
itunes.apple.com/lookup?bundleId=<<내 앱 번들 id>>
그러나 안드로이드 같은 경우에는 url이 아닌 또 다른 api를 사용해줘야 되고 이 과정에서 문제가 복잡해진다.
위와 같은 문제로 인해 Firebase에서 제공하는 Remote Config를 통한 앱 버전 관리 방법을 소개한다.
Remote Config란?
파이어베이스에서 제공하는 Remote Config(원격 구성) 기능은 앱에서 사용되는 설정 데이터를 로컬 환경에 저장하는 것이 아닌, 파이어베이스 서버에 저장하여 쓸 수 있도록 하는 서비스이다.
예를 들자면 앱에서 사용하는 메뉴들의 위치 순서를 변수에 저장하여 사용하고 있다면, 그 값을 remote config로 사용하게 되면 앱을 새로 업데이트 하지 않고 값을 변경해서 모든 유저들이 변경된 값을 사용할 수 있는 것이다.
이처럼 remote config를 사용하면 외부에서 변경할 수 있는 변수를 앱 내부에서 사용할 수 있는 것이다. 이 기능을 사용해 Remote Config 서비스에 앱의 최소 버전과 최신 버전의 값을 저장해놓고, 앱이 업데이트 될 때마다 이 값을 수정하여 앱이 현재 버전을 감지할 수 있도록 하는 것이 목표다.
먼저 Firebase 프로젝트로 들어가서 왼쪽 메뉴 아래쪽에 Remote Config를 선택하고 사용한다. Remote Config는 무료이기 때문에 부담없이 써도 된다.
매개변수 추가를 눌러서 매개변수를 추가한다. 매개변수 키는 json key라고 생각하면 되고, 기본 값은 json value라고 생각하면 된다.
매개변수로 latest_version과 min_version을 추가해준다.
매개변수를 추가하고 상단에 변경사항을 저장해주면 서버 설정은 끝이다. 남은 일은 플러터 앱에서 이 매개변수 값을 읽어오고 현재 버전과 비교한 후, 적당한 처리를 해주기만 하면 된다.
파이어베이스 RemoteConfig 서비스에 저장한 매개변수 값을 불러오기 위해 먼저 firebase_remote_config 패키지를 설치해준다.
따로 추가 설정해줄 것은 없어서 패키지만 설치해주고 사용하면 된다. 다만 파이어베이스와 앱이 연동되어있는 상태여야 한다. 만약 연동되지 않았다면 사용할 수 없다.
사용 방법은 아래와 같다. 본인은 getAppVersion이라는 함수를 정의해서 사용했다.
Future<void> getAppVersion() async {
RemoteConfig remoteConfig = await RemoteConfig.instance;
await remoteConfig.fetch(expiration: Duration(hours: 6));
await remoteConfig.activateFetched();
String minAppVersion = remoteConfig.getString('min_version');
String latestAppVersion = remoteConfig.getString('latest_version');
}
파이어베이스의 다른 기능들과 마찬가지로 instance 변수를 통해 함수를 호출한다.
fetch라는 함수는 실질적으로 서버와 통신하여 매개변수들을 읽는다. 인수로 expiration을 설정할 수 있는데, 서버의 매개변수 값을 얼마 간격으로 읽어올 것인지 설정할 수 있으며 기본 값은 12시간이다. 나는 6시간으로 설정해놨다.
fetch 함수가 수행됬다해서 매개변수가 최신화되는 것은 아니다. 값은 sdk에 일단 저장되어있지만 실제로 사용하려면 activateFetched 함수를 호출해서 그 값을 사용한다고 설정해줘야 한다. 함수가 호출된 이후에 get함수로 최신화된 매개변수 값에 접근할 수 있다. 여기서는 String 값을 불러와야해서 getString을 썼다.
현재 내 앱 버전 확인
현재 앱의 버전을 확인하는 가장 간단한 방법은 package_info 패키지를 사용하는 것이다.
다음 함수를 호출하면 앱의 버전과 빌드 넘버를 확인할 수 있다.
import 'package:package_info/package_info.dart';
PackageInfo packageInfo = await PackageInfo.fromPlatform();
String version = packageInfo.version;
String buildNumber = packageInfo.buildNumber;
자, 이제 앱의 최소 버전과 최신 버전 그리고 현재 버전을 모두 알 수 있게 됬다. 남은 것은 이 정보를 토대로 유저에게 업데이트를 강제할 것인지, 유도할 것인지 확인해주어야 한다.
업데이트 감지
remote config 서비스를 사용하여 getAppVersion 함수를 정의했고 호출하면 앱의 버전 값을 얻을 수 있게 되었다. 그렇다면 이 getAppVersion 함수를 어느 타이밍에 호출하면 좋을까?
일정 시간마다 확인
이 방법은 매우 좋지 않다. RemoteConfig 서비스는 무료이긴 하지만 트래픽이 과부하가 되면 서버에 문제가 생길 수 있다. 일정 시간마다 업데이트를 시키게 되면 쓸데 없는 트래픽이 증가되어 문제가 생길 수 있다. 또한 앱 사용 중간에 일어난다는 문제점도 있다.
스플래쉬 화면에서 확인
스플래쉬 화면에서 업데이트를 확인하는 방식은 많은 앱이 사용하는 방식이다. 이 방식을 사용해도 되지만 RemoteConfig 서비스가 생각보다 빠른 통신이 이루어지는 것이 아니라서 앱 사용자 입장에서 로딩 시간이 길어질 수 있다는 단점이 있다.
일정 시간마다 스플래쉬 화면에서 확인
예를 들면 하루에 1번 스플래쉬 화면에서 업데이트를 확인하는 방식이다. 일정 시간마다 확인하는 것보다 트래픽도 덜 발생하며 스플래쉬 화면에서만 작동하기 때문에 앱 사용자들도 만족할 것이다.
번외) FCM을 통해 업데이트
Firebase Cloud Message를 통해 앱 사용자들에게 업데이트 정보를 전달해주는 방식이다. 사실 이 방식을 쓰면 Remote Config를 사용하지 않아도 된다. 다만 단점은 메시지 수신을 못받는 경우가 존재할 수 있고, 모든 유저에게 메시지를 보내는 것이기 때문에 소수의 유저를 위해 메시지를 한번 더 보내기엔 위험하다는 단점이 있다.