with YouTube Data API (3/3)
SDK Version : Flutter 2.2.3, Dart 2.13.4
OS : Windows 11
IDE : Android Studio
Target : Android
Firebase(이하 파이어베이스)는 구글 클라우드 플랫폼에 기반하여 백엔드 부분을 쉽게 구축할 수 있도록 한 개발 플랫폼이다. 대표적으로 인증, 데이터베이스, 스토리지, 호스팅 등을 제공한다.
여기서는 파이어베이스와 플러터를 연동하여 파이어베이스의 Firestore 데이터베이스에서 데이터를 가져오는 과정을 다뤄본다. 데이터베이스에는 Retrofit을 통해서 가져온 유튜브 데이터 중에서 id, title, thumbnails url, viewCount을 콘솔을 통해서 직접 등록하여 사용할 것이다. 가져온 정보를 바탕으로 플러터 YouTube 패키지 사용하기의 예제에서 retrofit을 걷어내고 파이어베이스로 대체한다.
YouTube Data API는 기본적으로 하루 사용량에 대한 제한이 있다. 사용량 증가를 별도로 판매하지도 않는다. 따라서 이런 식으로 데이터베이스를 구축하여 사용하면 할당량 제한에 대한 걱정을 하지 않아도 된다. 물론 요청량이 파이어베이스 무료 제공량을 벗어나면 비용이 발생하겠지만 그 정도로 서비스가 성공한다면 좋은 일이 아닐까?
플러터에서 파이어베이스를 사용하는 것 자체는 비교적 간단하지만 연동하기 위한 과정은 다소 길다. 설정할 것이 많다는 뜻이다. 하나씩 해보자.
파이어베이스에 접속하여 로그인한다. 그러면 파이어베이스 콘솔로 접속된다. 프로젝트 만들기를 선택한다.
프로젝트 이름을 입력하고 각 단계를 진행한다.
프로젝트를 생성이 완료되면 다음과 같은 화면이 나타난다. 여기서 안드로이드 아이콘을 누른다.
먼저 등록하려는 앱의 패키지 이름을 입력해야 한다.
패키지명은 플러터 프로젝트에서 andoid app 내에 있는 build.gradle 파일의 applicationId에서 확인할 수 있다.
앱 등록을 누르면 아래 화면이 나온다. 여기서 google-service.json을 다운로드한다.
다운로드한 google-services.json 파일은 아래 경로(android/app)에 넣는다. 패키지명을 확인했던 build.gradle 파일이 있는 경로와 동일하다. 그 후 build.gradle에 'apply plugin: 'com.google.gms.google-services'를 추가한다.
안드로이드 네이티브 기준으로 파이어베이스 BoM과 구글 Analytics를 사용하려면 추가적으로 dependencies에 다음을 추가하라는 안내가 있을 것이다. BoM은 파이어베이스와 관련된 여러 라이브러리의 버전을 BoM 버전 하나로 관리해주는 것이고 구글 Analytics는 앱 사용에 관련된 통계를 볼 수 있는 솔루션이다. 플러터는 iOS와 안드로이드 모두 지원하는 별도의 패키지(FlutterFire)를 사용하기 때문에 생략하고 진행한다.
dependencies {
implementation platform('com.google.firebase:firebase-bom:28.4.2') // 생략
implementation 'com.google.firebase:firebase-analytics-ktx' //생략
implementation 'com.android.support:multidex:2.0.1'
}
여기서 implementation 'com.android.support:multidex:2.0.1'은 꼭 추가해준다. 이 설정은 멀티덱스 지원을 하도록 하는 것이다. 추후에 빌드 시 (안드로이드 API 20 이하 버전에서) 앱이 참조하는 라이브러리에 메서드가 64K(65536) 개를 초과할 때 발생하는 에러를 막기 위함이다.
또한 같은 파일 내에 패키지명(applicationId)을 확인했던 defaultConfig에 multiDexEnabled true를 추가해야 한다.
defaultConfig {
applicationId "com.retrofit.retrofit_pkg"
minSdkVersion 17
targetSdkVersion 30
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
multiDexEnabled true
}
또한 프로젝트의 build.gradle에 classpath 'com.google.gms:google-services:4.3.10를 추가한다.
이전에는 app 수준의 build.gradle이었고 이번에는 아래 화면과 같이 프로젝트 수준의 build.gradle인 것에 유의한다. 둘은 서로 다른 파일이다.
여기까지 완료 후 콘솔로 이동한다.
콘솔에서 데이터베이스를 생성하고 데이터를 직접 수동으로 등록할 것이다. 먼저 데이터베이스를 만든다.
테스트 모드로 설정하고 Cloud Firestore 위치는 기본 상태 그대로 하여 사용 설정을 마무리한다.
사용 설정을 마치면 아래와 같이 빈 데이터베이스가 생성된다. 여기서 컬렉션 시작을 누른다.
컬렉션 ID를 입력하고 다음으로 넘어간다. 컬렉션 ID는 추후 데이터베이스 접근 시 사용하게 된다. 문서 ID는 직접 입력해도 되지만 힘드니 자동 ID를 눌러서 자동으로 생성한다. 그리고 저장할 데이터의 필드, 값을 입력한다. 데이터는 retrofit으로 받아서 로그로 출력해서 가져왔다. (이것 또한 자동화가 가능하다. 받은 데이터를 그대로 파이어베이스 데이터베이스에 쓰는 프로그램을 만들면 된다.) 로그에 보이는 데이터 순서는 id, title, thumnail, viewCount 순이다.
[log] dyRsYk0LyA8
[log] BLACKPINK - 'Lovesick Girls' M/V
[log] https://i.ytimg.com/vi/dyRsYk0LyA8/mqdefault.jpg
[log] 491253632
데이터를 입력하고 저장하면 다음과 같이 된다. 이제 데이터베이스에 실제 데이터가 추가되었으니 읽어오는 코드를 작성하면 된다.
플러터에서 파이어베이스를 사용하기 위한 패키지를 등록한다. firebase_core는 기본적으로 추가되어야 하고 그 외에 사용하고자 하는 파이어베이스 제품을 추가한다. 여기서 사용할 것은 firestore 데이터베이스만 사용하기 때문에 cloud_firestore만 추가한다. retrofit은 사용하지 않을 것이기 때문에 관련 패키지들은 제거해도 된다.
dependencies:
flutter:
sdk: flutter
retrofit: ^2.0.1 // 제거
json_annotation: ^4.0.1 // 제거
youtube_player_flutter: ^8.0.0
firebase_core: ^1.6.0
cloud_firestore: ^2.5.1
기존에 사용하던 데이터 모델을 파이어베이스에서 읽어올 데이터에 맞춰 변경한다. 간단하게 3개의 String 변수가 있으면 된다. json 직렬화도 필요 없다.
파이어베이스에서 데이터를 가져오는 부분은 다음의 init 메서드이다. 매개변수로 파이어베이스에서 생성한 컬렉션명을 넘겨준다. 그러면 해당 컬렉션에 있는 문서(docs)에 접근하여 해당 문서 내에 있는 데이터들을 필드명으로 접근해서 가져올 수 있다. snapshot()은 쿼리의 결과를 담은 stream을 리턴해주고 결괏값을 수신하면 listen에서 적절히 데이터를 추출하면 된다.
Future<void> init(String collection) async {
await Firebase.initializeApp();
FirebaseFirestore.instance
.collection(collection)
.snapshots()
.listen((event) {
event.docs.forEach((element) {
log("id : ${element.data()['id']}");
log("title : ${element.data()['title']}");
log("image : ${element.data()['image']}");
log("view : ${element.data()['view']}");
if (collection == 'my_youtube') {
videoIdList.add(element.data()['id']);
responseData[element.data()['id']] = DataModel(
title: element.data()['title'],
thumbnail: element.data()['thumbnail'],
viewCount: element.data()['viewCount']);
}
});
setState(() {
isLoading = true;
});
});
}
main의 전체 코드는 다음과 같다.
사용자 수준에서의 예제 앱 동작은 retrofit 사용할 때와 동일하다.
이 외 더 필요한 파이어베이스 사용법은 다음 공식 가이드 문서를 참고하면 된다.
https://firebase.flutter.dev/docs/firestore/usage