Trong series hướng dẫn làm việc với Firebase, các bạn đã biết cách push notification, cách xác thực tài khoản… thậm chí là phát hiện khuôn mặt bằng Firebase. Từ ngày về cùng đội với Google, Firebase ngày càng có nhiều tính năng hữu ích, giúp cho việc phát triên ứng dụng di động trở nên đơn giản hơn rất nhiều.
Hôm nay mình sẽ giới thiệu tới các bạn một tính năng rất quan trọng, cũng như được sử dụng rất nhiều của Firebase. Đó là tính năng Firebase remote config.
Hiểu nôm na thì đây là tính năng cho phép bạn thay đổi những thông số cài đặt của ứng dụng từ xa. Để hiểu rõ hơn, chúng ta sẽ cùng nhau tìm hiều kỹ hơn xem firebase remote config là gì và nó có thể làm được những gì.
Nội dung chính của bài viết
1. Firebase Remote Config là gì?
Là một phần của dịch vụ Firebase, Remote Config là dịch vụ cloud với mục đích giúp đơn giản quá trình phát triển ứng dụng mobile và cả testing ứng dụng.
Đúng như tên của chức năng, Firebase Remote Config là dịch vụ cho phép bạn thay đổi thiết lập ứng dụng mà không cần phải cài đặt/update ứng dụng.
Để bạn dễ hình dung hơn, mình lấy ví dụ thế này. Ứng dụng của bạn được tích hợp quảng cáo Admob và FAN. Bạn muốn hôm nay chỉ hiển thị Admob, ngày mai thì FAN. Thậm chí vào một ngày đẹp trời, bạn trúng con lô thế là muốn chia sẻ niềm vui với người dùng bằng cách tắt hết quảng cáo đi.
Không lẽ mỗi lần bạn thay đổi cài đặt như trên lại bắt người dùng phải update ứng dụng. Mà có phải ai cũng rảnh để update đâu.
Đây chính là một case mà Firebase Remote Config giúp bạn giải quyết vấn đề.
2. Firebase Remote Config có thể làm được gì?
Với Remote config, bạn có thể làm được rất nhiều thứ. Mình có thể đề xuất một vài ý tưởng như:
- Có thể thay đổi cài đặt mặc định của ứng dụng một cách nhanh chóng. Ví dụ: Bạn có hình ảnh banner để quảng bá trong ứng dụng nhân dịp đầu năm mới. Sau đó thì bạn ẩn banner đó đi. Ngoài ra, bạn còn có thể kiểm soát mức độ hiển thị banner bằng các giá trị cấu hình từ xa mà không cần chờ người dùng cập nhật ứng dụng.
- Có thể tùy chỉnh giao diện người dùng cho tùy từng đối tượng khác với giá trị mặc định. Ví dụ, bạn muốn thay đổi giao diện ứng dụng cho người dùng là nữ, khác với người dùng là nam. Điều này có thể thực hiện bất cứ lúc nào.
- Ý tưởng sử dụng thứ 3, cũng là một khả năng quan trọng của Firebase Remote Config. Đó là việc sử dụng remote config để thực hiện A/B testing ứng dụng. Ví dụ, bạn muốn kiểm tra màu sắc của nút “Đặt hàng” tác động tới tỷ lệ chuyện đổi như nào? Với remote config, bạn có thể thay đổi màu của nút và theo dõi trước khi quyết định.
Trên đây chỉ một trong những khả năng của Remote Config mà mình đề xuất thôi. Với khả năng sáng tạo, bạn hoàn toàn có thể ứng dụng nó để tạo ra những tính năng tuyệt vời cho ứng dụng của bạn.
Mặc dù Remote Config hay là vậy, nhưng không phải lúc nào bạn cũng nên sử dụng nó. Cũng tùy trường mà dùng cho đúng.
3. Remote Config hoạt động như thế nào?
Firebase sẽ có bộ SDK mà bạn cần phải tích hợp vào ứng dụng. Bộ thư viện này sẽ fetch các giá trị cài đặt từ Firebase server. Nó sẽ có trách nhiệm fetch giá trị và lưu vào bộ nhớ điện thoại.
Nếu không thể lấy được các giá trị từ server thì giá trị mặc định sẽ được sử dụng.
Ngoài ra, Firebase sẽ lưu cache các giá trị trong khoảng thời gian 12 giờ. Nghĩa là trong khoảng thời gian này thì các giá trị cài đặt sẽ được lấy từ cache thay vì cứ phải request tới server để lấy giá trị mới.
Mấy khi ai thay đổi cài đặt ứng dụng theo kiểu real time đâu nhỉ?
Phần tiếp theo, mình sẽ tạo một ứng dụng sử dụng Remote Config, các bạn cùng mình bắt tay vào code nhé.
4. Thực hành tạo ứng dụng
Ứng dụng này sẽ đơn giản là hiển thị một dòng chữ Welcome với 3 tham số cấu hình: màu chữ, cỡ chữ và nội dung dòng thông báo welcome.
Giờ bắt đầu nhé!
#Tích hợp Firebase vào ứng dụng
Trước khi tích hợp, bạn cần phải đăng ký ứng dụng với Firebase trên web. Bạn vào màn hình firebase console để thực hiện khai báo.
Sau đăng ký xong, bạn tải file cấu hình google-service.json
và thêm vào thư mục app của dự án.
#Thêm Firebase SDK vào dự án
Phần này bạn cần thêm các dependencies cần thiết của Remote Config vào build.gradle của app
dependencies { implementation 'com.google.firebase:firebase-config:16.1.0' // Remote Config gradle dependency implementation 'com.google.firebase:firebase-core:16.0.4' // Firebase gradle dependency } apply plugin: 'com.google.gms.google-services' // Google Services plugin
Version của thư viện có thể thay đổi theo thời gian nhé.
Sau đó thêm/chỉnh sửa build.gradle của dự án.
buildscript { repositories { google() jcenter() } dependencies { classpath 'com.android.tools.build:gradle:3.2.1' classpath 'com.google.gms:google-services:4.0.1' // Project Level Google Services dependency } }
#Tạo giao diện ứng dụng
Ứng dụng rất đơn giản, chỉ có một TextView thôi. Bạn thiết kế thế nào cũng được. Đây là ví dụ của mình.
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <TextView android:layout_width="wrap_content" tools:text="Welcome to the app" android:id="@+id/text" android:layout_marginTop="32dp" android:layout_centerHorizontal="true" android:layout_height="wrap_content" /> <Button android:layout_width="wrap_content" android:text="FETCH" android:id="@+id/fetch" android:layout_centerInParent="true" android:layout_height="wrap_content" /> </RelativeLayout>
Sau đó bạn tạo mới một MainActivity. Nhớ khai báo activity trong Manifest.xml đấy.
Trong MainActivity, chúng ta khởi tạo đối tượng RemoteConfig
public class MainActivity extends AppCompatActivity { private FirebaseRemoteConfig firebaseRemoteConfig; private Button button; private TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button = findViewById(R.id.fetch); textView= findViewById(R.id.text); // Fetch singleton FirebaseRemoteConfig object firebaseRemoteConfig = FirebaseRemoteConfig.getInstance();
Ngoài ra, bạn nên bật chế độ developer mode. Mục đích là để cho phép bạn reload lại cache bất kỳ lúc nào. Còn với chế độ product, bạn sẽ bị giới hạn reload cache tối đa 5 lần/ giờ.
firebaseRemoteConfig.setConfigSettings(new FirebaseRemoteConfigSettings.Builder() .setDeveloperModeEnabled(true) .build());
#Tạo thông số cài đặt mặc định
Như mình đã đề cập ở trên, nếu trường hợp Firebase SDK không thể lấy được giá trị cài đặt từ server vì nhiều lý do. Ứng dụng sẽ sử dụng các giá trị cài đặt mặc định.
<?xml version="1.0" encoding="utf-8"?> <defaultsMap> <entry> <key>text_str</key> <value>Welcome to the app</value> </entry> <entry> <key>text_str</key> <value>14</value> </entry> <entry> <key>text_color</key> <value>#FF0000</value> </entry> </defaultsMap>
Sau đó thì sử dụng API đế set giá trị mặc định
firebaseRemoteConfig.setDefaults(R.xml.default_map)
Nếu bạn không muốn định nghĩa bằng XML thì có thể định nghĩa bằng JAVA. Đều được.
Map<String,Object> map =new HashMap<>(); map.put("text_str","Welcome to the app"); map.put("text_size",14); map.put("text_color","#FF0000");
#Cách nhận các giá trị cài đặt
Firebase SDK cung cấp sẵn API để bạn làm điều này một cách dễ dàng. Bạn có thể thử dụng API sau: firebaseRemoteConfig.get<>()
.
Như mình đã nói ở trên, nếu API này không lấy được giá trị từ server thì nó sẽ tự động lấy từ giá trị mặc định.
Và một điểm nữa là khi bạn gọi hàm này thì nó không thực sự request tới server, mà nó sẽ lấy từ active config trước.
textView.setTextColor(Color.parseColor(firebaseRemoteConfig.getString("text_color"))); textView.setTextSize((float) firebaseRemoteConfig.getValue("text_size").asDouble()); textView.setText(firebaseRemoteConfig.getString("text_str")); }
Để nhận giá trị mới nhất từ server, bạn có thể sử dụng API: firebaseRemoteConfig.fetch()
Mặc định thì thời gian cache một giá trị cài đặt là 12 giờ, và bạn có thể thay đổi giá trị này bằng hàm fetch(long)
, tham số được tính theo đơn vị giây.
Trong khoảng thời gian chưa hết hạn cache của giá trị, dù bạn gọi hàm fetch()
thì nó cũng không request tới server, mà sẽ trả giá trị từ cache.
Như trong ví dụ dưới đây, mình đặt giá trị cache là 0, tức là luôn lấy giá trị mới nhất từ server.
button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { /* This will initiate fetching of parameters. We have set the expiry time as 0 which will ensure we get fresh parameters every time */ firebaseRemoteConfig.fetch(0).addOnCompleteListener(new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull Task<Void> task) { if (task.isSuccessful()){ Toast.makeText(MainActivity.this, "Activated", Toast.LENGTH_SHORT).show(); }else { Toast.makeText(MainActivity.this, "Not Activated", Toast.LENGTH_SHORT).show(); } } }); } });
Lưu ý là hiện tại mình chưa tạo bất kỳ giá trị cài đặt nào trên Firebase console. Nên dù bạn có gọi hàm fetch() bao nhiêu lần thì cũng chỉ nhận được giá trị cài đặt mặc định mà thôi.
Và đây là toàn bộ code của MainActivity.
public class MainActivity extends AppCompatActivity { private FirebaseRemoteConfig firebaseRemoteConfig; private Button button; private TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button = findViewById(R.id.fetch); textView= findViewById(R.id.text); firebaseRemoteConfig = FirebaseRemoteConfig.getInstance(); firebaseRemoteConfig.setConfigSettings(new FirebaseRemoteConfigSettings.Builder() .setDeveloperModeEnabled(true) .build()); firebaseRemoteConfig.setDefaults(R.xml.default_map); /* Setting color, size and string for TextView using parameters returned from remote config server */ textView.setTextColor(Color.parseColor(firebaseRemoteConfig.getString("text_color"))); textView.setTextSize((float) firebaseRemoteConfig.getValue("text_size").asDouble()); textView.setText(firebaseRemoteConfig.getString("text_str")); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { /* This will initiate fetching of parameters. We have set the expiry time as 0 which will ensure we get fresh parameters every time */ firebaseRemoteConfig.fetch(60*5).addOnCompleteListener(new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull Task<Void> task) { if (task.isSuccessful()){ Toast.makeText(MainActivity.this, "Activated", Toast.LENGTH_SHORT).show(); /* Activiting fetched parameters. The new parameters will now be available to your app */ firebaseRemoteConfig.activateFetched(); }else { Toast.makeText(MainActivity.this, "Not Activated", Toast.LENGTH_SHORT).show(); } } }); } }); } }
Giao diện ứng dụng khi chạy.
#Thêm giá trị cài đặt trên Firebase console
ở phần này, chúng ta sẽ cùng nhau học cách thêm các giá trị cài đặt trên remote config server.
Bạn vào Firebase Console và chọn dự án mà bạn đã tạo ở bước trên.
Sau đó chọn Grow > Remote Config
Bây giờ bạn chọn “Add your first parameter”, bạn sẽ được chuyển đến màn hình thêm giá trị. Bạn cần chút ý là các key cho mỗi giá trị cài đặt cần phải giống key mà bạn đã tạo ở trong android app.
Sau khi đã hoàn thành việc thêm trên firebase console, giờ bạn mở Android app lên và nhấn nút fetch xem sao.
Bạn thấy sự thay đổi chưa? App đã đổi màu sắc mà không cần phải cài đặt lại app.
#Tạm kết
Đến đây mình xin tạm dừng bài hướng dẫn về remote config. Nếu bạn tính năng này được triển khai đúng cách, sẽ giúp bạn kiểm soát hoàn toàn hành vi của ứng dụng từ xa ở trên tất cả phiên bản.
Mình hi vọng qua bài viết này, bạn hiểu hơn về firebase. Nếu bạn có ý tưởng gì thú vị, xin đừng ngần ngại để lại bình luận bên dưới nhé.
💦 Đọc thêm về lập trình Android:
Chào bạn! Cảm ơn bạn vì bài viết rất hay! Mình có ý tưởng thế này không biết bạn có hướng dẫn được không? Mình muốn dùng Remote config để thay đổi hình nền của activty định dạng file kiểu jpeg hoặc png. Cám ơn bạn!
Chào bạn,
Mình nghĩ ý tưởng của bạn hoàn toàn có thể làm được. Khi activity bạn khởi động (ví dụ trong onStart()), bạn lấy giá trị trong remote config để set background là được mà
Có thể viết một bài sử dụng remote config, để bật tắt 1 function java trong android không bạn.