[Flutter] Amplitude 설정하기
이번 글은 Amplitude Developer Center의 Flutter SDK 글을 참고하여 작성하였습니다.
https://www.docs.developers.amplitude.com/data/sdks/flutter/
Amplitude란?
우리가 웹 또는 앱을 만들고 배포를 하면 모르는 사용자들이 들어와 이런저런 기능들을 사용하게 됩니다.
단순히 개인 프로젝트나 서비스를 사용할 사람들이 정해진 경우엔 괜찮지만, 마케팅 등을 통해 익명의 사용자들을 더 많이 모으고 싶은 경우 이 사람들이 우리 서비스에서 어떤 행동을 하는 지 주목할 필요가 있습니다.
일단 사용자의 행동을 살펴보면 여러 가지 장점이 있습니다.
- 우리 아이디어가 정말 괜찮은지 뇌피셜이 아니라 수치적으로 증명할 수 있습니다.
- 사용자의 불편사항(ex. 특정 기능에서 지루함을 느끼는 등)을 파악하여 개선할 수 있습니다.
- 서비스의 기능 별 사용자들의 여러 지표를 보고 앞으로 어떻게 발전시켜 나가야 할지 객관적으로 알 수 있습니다.
이외에도 여러 장점이 있지만, 결론적으로 이런 활동들은 돈이 될 수 있습니다. 😆
사용자의 니즈를 맞춰야 유지율이 높아지고, 유지율이 높아지면 의미 있는 마케팅을 할 수 있고, 사용자가 많아지면 광고를 해서 수익을 창출할 수 있기 때문입니다.
따라서 사용자의 행동 패턴을 살펴보기 위해, 우리는 Amplitude, Google Analytics 등의 분석 툴을 사용하게 됩니다.
그중 Amplitude는 Product Analytics 분야에서 가장 유명하고, 무엇보다 무료 플랜이 좋아서 웬만하면 무료로 사용 가능합니다!
Amplitude는 다음과 같은 기능을 제공합니다.
- 앱 또는 웹 사용자들이 사용 시 수행하는 행동들을 수집합니다. (User Activity)
- 이벤트(앱 접속, 특정 버튼 클릭)
- 이벤트 내부 속성 값(최초 접속인지, 버튼을 클릭할 당시 사용자의 잔액)
- 사용자 속성(국가, 접속 기기, 플랫폼 정보)
- 수집한 행동(이벤트)들을 차트로 만들 수 있습니다. (Chart)
- 생성된 차트들을 위젯 형식으로 모아 표시합니다. (DashBoard)
- 특정 기간, 특정 행동을 하는 사용자들의 집단(Group)을 정의해 분석할 수 있습니다. (Cohort, 유료)
- 저장된 데이터들을 쿼리 형식으로 검색할 수 있습니다. (SQL, 유료)
이들 중 Flutter와 연관되는 부분은 User Activity 정도인데, 이벤트를 어떻게 보내도록 설정할 수 있기 때문입니다.
따라서 이번 포스팅에는 Flutter에서 어떻게 Amplitude에 이벤트와 속성 값을 보낼지 알아보도록 하겠습니다 🏃
기본 설정
1. Amplitude 홈페이지에 접속해줍시다.
2. 회원가입을 합니다.
이때, 회사 이름과 규모는 있으면 적고, 없으면 대충 서비스 이름을 적어줍시다 ^_^
이메일 인증을 마치면, 아래와 같은 화면이 나오는데 여기서 "Your org URL"은 반드시 기억해야 합니다.
Amplitude 로그인을 할 때 항상 입력해줘야 해요!
여기서 "Create 버튼"을 누르면 어떤 목적으로 Amplitude를 사용하는지 나오게 됩니다.
이때 데모를 누르면 바로 데모 페이지로 연결되니 다시 재접속하시고.. 일반적으로 다음과 같은 화면이 뜨게 됩니다.
3. Flutter SDK 설정하기
여기서 우리는 Flutter SDK를 선택하면 아래 화면이 나오게 됩니다!
Flutter 코드 내에서 Dependency 추가, ios 설정 방법이 있고 마지막에 키 값을 이용해 Flutter SDK를 initialize 하는 방법이 나와있습니다.
사진에서 빨간 줄로 키 값을 가렸는데, 절대 github 등에 노출하면 안 됩니다!
아래 Amplitude config 설정 파일에 노출 방지 방법도 나와있으니 참고하시면 되겠습니다.
1) Dependency 추가하기
pubspec.yaml 파일 - dependencies 아래 추가해주고, 터미널에 명령어 "flutter pub get"을 치거나 파일 저장하기를 누르면 됩니다.
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
amplitude_flutter: ^3.2.1
2) SDK 초기화(인스턴스 설정)
앞으로 인스턴스를 통해 이벤트를 만들게 되는데, 그전에 먼저 인스턴스가 우리 Amplitude를 바라보게끔 설정해줘야 합니다.
설정 부분은 따로 config 파일을 만들어 두는 것이 나중에 프로젝트 규모가 커졌을 때 편합니다.
파일은 이런 식으로 작성하였고, 키 값은 각자 위에서 받은 값으로 세팅해주면 됩니다.
import 'package:amplitude_flutter/amplitude.dart';
class Analytics_config {
static late Amplitude analytics =
Amplitude.getInstance(instanceName: "suhwanc");
Future<void> init() async {
// Initialize SDK
analytics.init('여기 키 값');
}
}
파일 위치는 main.dart 파일과 동일한 위치에 두었습니다.
3) main.dart 에서 초기화 선언하기
초기화 클래스 파일을 만들었으니, 앱 최초 실행 시 한 번 초기화 선언을 해주면 됩니다.
선언 부분은 main 함수에서 runApp 위에 위치시켜줍시다.
여기서 "WidgetsFlutterBinding.ensureInitialized()" 코드를 추가해주지 않으면 오류가 발생하는데,
SDK 초기화 이전에 Flutter의 위젯 바인딩이 보장되어야 하기 때문입니다.
(SDK 초기화가 네이티브(ios, aos) 코드에 접근하기 때문에 그 전에 플랫폼 채널의 바인딩이 필요해집니다)
더 자세히 알고 싶다면 다음 블로그 참조
import 'package:flutter/material.dart';
import 'package:flutter_amplitude_demo/analytics_config.dart';
import 'package:flutter_amplitude_demo/home_screen.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
Analytics_config().init(); //여기 선언
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter - Amplitude Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: HomeScreen(),
);
}
}
4) ios - podfile 설정
해당 경로의 Podfile에 기존 주석 처리되어있는 "platform : ios, '9.0'" 부분을 다음과 같이 바꿔줍니다.
이제 우리 Flutter 코드는 Amplitude에 이벤트를 쏠 준비가 끝났습니다.
마지막으로 Amplitude 홈페이지에서 SDK 설정이 잘 되었는지 테스트하는 코드가 있습니다.
이 코드를 통해 이벤트를 홈페이지에 보낸 후에야 Finish 버튼을 누를 수 있고, 설정한 이벤트를 확인할 수 있습니다.
만들어둔 설정 파일에 그대로 복사 후, Flutter run으로 앱을 실행시켜줍시다.
import 'package:amplitude_flutter/amplitude.dart';
import 'package:amplitude_flutter/identify.dart';
import 'package:flutter/material.dart';
class Analytics_config {
static late Amplitude analytics =
Amplitude.getInstance(instanceName: "suhwanc");
Future<void> init() async {
// Initialize SDK
analytics.init('키 값');
// Enable COPPA privacy guard. This is useful when you choose not to report sensitive user information.
analytics.enableCoppaControl();
// Set user Id
analytics.setUserId("test_user");
// Turn on automatic session events
analytics.trackingSessionEvents(true);
// Log an event
analytics.logEvent('MyApp startup',
eventProperties: {'friend_num': 10, 'is_heavy_user': true});
// Identify
final Identify identify1 = Identify()
..set('identify_test',
'identify sent at ${DateTime.now().millisecondsSinceEpoch}')
..add('identify_count', 1);
analytics.identify(identify1);
// Set group
analytics.setGroup('orgId', 15);
// Group identify
final Identify identify2 = Identify()..set('identify_count', 1);
analytics.groupIdentify('orgId', '15', identify2);
}
}
4. 이벤트
세팅이 끝났다면, 이벤트를 추가하는 일은 정말 간단합니다.
기본 이벤트
가장 기초적인 이벤트 방법입니다.
인스턴스에 logEvent라는 메서드를 사용하고, 하나의 인자만 넣으면 됩니다.
넣은 하나의 인자는 이벤트 타입 이름이 되는데, 우리가 알아볼 수 있도록 작성하는 것이 좋습니다.
Analytics_config.analytics.logEvent("suhwanc");
전체 코드
void main() {
WidgetsFlutterBinding.ensureInitialized();
Analytics_config().init();
Analytics_config.analytics.logEvent("suhwanc"); //기본 이벤트
runApp(MyApp());
}
코드를 실행시키면 Amplitude의 User Look-up에 다음과 같은 이벤트가 표시됩니다.
다른 분석 툴과 비교해 Amplitude는 이벤트 발생 표시가 정말 빠르게 뜨는 편입니다.
우측 상단에 "Live event updates"를 활성화시키면 1분 이내로 이벤트가 표시되는 것을 볼 수 있습니다.
여기서 파란 글자의 "User ID"를 누르면 이벤트에 대한 좀 더 자세한 정보를 알 수 있습니다.
사용자에 대한 정보입니다.
이벤트를 몇 개 발생시켰는지, 본 화면은 몇 개인지, 위치는 어디인지, OS는 무엇인지 등 생각보다 많은 정보를 알 수 있습니다.
이런 정보들은 유저 프로퍼티라고 하는데, 말 그대로 유저에 대한 정보. 특정 이벤트에 종속적이지 않은 정보들을 담을 수 있습니다.
유저 프로퍼티에 설정 방법은 밑에서 자세히 설명할 예정입니다.
왼쪽은 특정 사용자의 이벤트 스트림(타임라인)을 의미합니다.
분석 시 사용자들이 어떤 Flow로 우리 앱을 사용하는지 또는 충돌이 발생한 경우 어떤 Flow로 발생했는지 알 수 있습니다.
오른쪽은 특정 이벤트에 대한 정보들입니다.
현재 기초 이벤트를 설정했기 때문에, 이벤트에 대한 프로퍼티는 발생 시간 정도뿐입니다. 그밖에 유저 프로퍼티가 있습니다.
프로퍼티 이벤트
이벤트에는 우리가 원하는 프로퍼티를 설정할 수 있습니다.
만약 노래를 저장하는 앱이라면, 사용자가 과연 어떤 노래를 저장할까?라는 궁금증이 생길 수 있는데, 이 경우 클릭 이벤트의 속성 값에 해당 노래의 이름 또는 가수를 저장하면 Amplitude 콘솔 화면에서 볼 수 있습니다.
Analytics_config.analytics
.logEvent("곡 추가", eventProperties: {"노래명": "오래된 노래"});
이 경우 두 개의 인자가 필요한데, 첫 번째 인자는 동일하게 이벤트의 이름, 두 번째 인자는 프로퍼티입니다.
프로퍼티는 Map<String, Dynamic> 형식으로 저장할 수 있으니, value 부분에 정수도 들어갈 수 있습니다. (당연히 변수도 가능!)
또한 다음과 같이 배열을 사용하면 하나의 프로퍼티에 여러 개 값을 추가할 수 있습니다.
Analytics_config.analytics.logEvent("곡 추가", eventProperties: {
"노래명": ["오래된 노래", "눈의 꽃"]
});
여러 개의 프로퍼티도 당연히 가능합니다.
Analytics_config.analytics
.logEvent("곡 추가", eventProperties: {"노래명": "오래된 노래", "가수": "스탠딩 에그"});
결과 화면입니다.
아까와 다르게 우측 하단에 Event Properties가 생겼고, 우리가 원하는 정보를 볼 수 있게 되었습니다.
플러시 이벤트
Amplitude는 Flutter 코드에서 이벤트가 발생할 때마다 저장하고 있지 않습니다. 거의 모든 분석 툴은 버퍼 저장 방식을 사용하는데,
이벤트가 발생하면 일단 버퍼에 저장하고, 주기적으로 한꺼번에 이벤트들을 올려 보내는 방식입니다.
하지만 강제적으로 이벤트를 보낼 방법이 있는데, 이것이 플러시 이벤트입니다.
아래 코드 실행 시, 현재까지 버퍼에 저장된 이벤트들을 올려 보냅니다.
Amplitude.getInstance().uploadEvents();
유저 프로퍼티
유저 프로퍼티는 우리 앱의 사용자를 이해하는데 도움이 되는 정보들입니다.
심지어 국가나 위치에 따라서도 앱을 사용하는 빈도가 다를 수 있기 때문에, 특정 지역을 저격하는 마케팅에 사용될 수도 있습니다.
주의할 점은 유저들의 프라이버시를 존중하는 선에서만 행동을 추적해야 한다는 것입니다.
Identify
유저 프로퍼티를 설정하기 위해선, 반드시 Idenify 패키지를 따로 import 해야 합니다.
import 'package:amplitude_flutter/identify.dart';
set
유저 프로퍼티를 설정하는 명령어입니다.
final Identify identify = Identify()
..set('노래 저장 수', 5)
..set('최고음', "2옥타브 시");
Analytics_config.analytics.identify(identify);
마찬가지로 Map<String, Dynamic> 형식으로 저장할 수 있으며
조금 다른 점은 위와 같이 체인 형식으로 여러 프로퍼티를 추가할 수 있습니다.
set 명령어를 사용해 Identify를 만들었다면, 잊지 말고 인스턴스에 identify 메서드를 사용해 추가해주어야 합니다.
결과 화면입니다. 유저 프로퍼티를 펼쳐보면 우리가 설정한 값들이 저장된 것을 알 수 있습니다.
만약 값이 변경되었다면, 우리가 Map을 사용하는 것처럼 key값에 따른 value를 재설정하면 됩니다!
set once
유저 프로퍼티 값을 한 번 설정하고, 다시는 변경하고 싶지 않을 때 사용하는 방법입니다.
"set" 과는 다르게, "set once" 메서드를 통해 Identify를 설정하면, 다시 호출해도 변경되지 않습니다.
주로 회원가입 날짜, 생일 등 절대 변경되지 않을 만한, 변경되면 안 되는 정보들에 대해 설정합니다.
final Identify identify1 = Identify();
identify1.setOnce('sign_up_date', '2015-08-24');
Amplitude.getInstance().identify(identify1);
final Identify identify2 = Identify();
identify2.setOnce('sign_up_date', '2015-08-24');
Amplitude.getInstance().identify(identify2);// is ignored
add
유저 프로퍼티에 특정 값을 세팅할 수도 있지만, 기존 값에 플러스 마이너스를 해야 할 상황이 생길 수 있습니다.
예를 들어 특정 사용자의 특정 기능 실행 빈도를 알고 싶다면, 기능 실행 시 기존 빈도수에 +1씩 해주는 방법이 있습니다.
identify.add('추가 이벤트 빈도', 1);
유저 프로퍼티 삭제하기
이벤트 프로퍼티의 경우, 코드에서 지운 후 다시 배포하면 이벤트가 발생하지 않겠지만
유저 프로퍼티는 코드를 지워도 특정 유저에 종속되어 프로퍼티 값이 남게 됩니다.
이 경우, Map에서 지우는 방법이 필요하게 됩니다.
모두 삭제하기
clearUserProperties 메서드를 사용하는 방법으로, 생각보다 유용합니다.
변경된 Identify를 그대로 적용시키고 싶다면, 아예 포맷시킨 후 적용하는 것이 깔끔하기 때문입니다.
Amplitude.getInstance().clearUserProperties();
부분 삭제하기
remove 메서드를 통해 특정 프로퍼티만을 지울 수 있습니다.
만약 없는 프로퍼티라면, 아무 일도 발생하지 않습니다.
const array = ["some_string", 56];
final Identify identify = Identify()
..remove("ab-tests", "new-user-test")
..remove("some_list",array);
Amplitude.getInstance().identify(identify);
유저 ID 설정하기
일반적으로 유저 ID는 유니크한 것이 좋습니다.
Amplitude 세팅 시, 대부분 "test_user"로 세팅하는 코드를 한 번쯤 실행하게 됩니다.
Amplitude.instance().setUserId("test_user");
필자의 경우 미리 이 부분을 지워두는데, 그렇게 하면 Amplitude가 알아서 유니크한 유저 ID값을 만들어 설정해줍니다.
시도해보진 않았으나, 원한다면 n번째 사용자는 User ID를 n번으로 사용하는 것도 보는 재미가 있을 것 같긴 합니다 🤔
결과 화면
.gitignore 설정하기
마지막으로 우리가 config 설정 시 사용했던 Amplitude SDK key값을 보호하기 위해 .gitignore 설정을 해주어야 합니다.
제 경우, lib 폴더에 analytics_config.dart 라는 파일을 만들었으므로 .gitignore에 다음 줄을 추가해주었습니다.
# Amplitude key
lib/analytics_config.dart
이번 포스팅을 위해 사용된 코드들은 아래 저장소에서 확인해볼 수 있습니다!
https://github.com/suhwan-cheon/flutter_amplitude_demo