รู้จัก Firebase Remote Config ตั้งแต่ Zero จนเป็น Hero
Firebase Remote Config เป็นบริการ Cloud ที่จะทำให้เราควบคุมการเปลี่ยนโฉมแอพ, การกำหนดลูกเล่นการใช้งาน และการตั้งค่าต่างๆแบบ On The Fly ง่ายๆได้ดังใจ แถมฟรีอีกด้วย ทั้งยังสามารถเลือกกลุ่มผู้ใช้ที่จะได้รับทั้งแบบ เฉพาะกลุ่ม หรือ แบบทั้งหมด ก็ได้ โดยผ่าน Firebase Console ซึ่งไม่ต้องดาวน์โหลดและอัพเดทแอพแต่อย่างใด
การทำงานของ Firebase Remote Config
ภายใน Remote Config นั้นจะมี library ที่จะทำหน้าที่ในการดึงค่า parameter values ต่างๆทั้งจากใน in-app และ server-side มา cache เก็บไว้ เพื่อให้เราเรียกใช้ได้อย่างมีประสิทธิภาพตามต้องการ
โดยปกติแล้ว Remote Config จะดึงค่าเริ่มต้นจาก in-app มาใช้งานก่อน แต่หากคุณต้องการเปลี่ยนแปลงค่าดังกล่าว คุณจะต้องไปสร้าง parameter ที่มีชื่อเดียวกับที่คุณสร้างใน in-app ที่เมนู Remote Config ใน Firebase Console โดยสามารถสร้างทั้งแบบ default value และ conditional values(กำหนดค่าแบบมีเงื่อนไข) ที่ server-side ได้
การลำดับความสำคัญของ parameter values แบ่งออกเป็น 2 กรณี
- Remote Config Server (กรณีที่กำหนดค่า parameter ใน Firebase Console)
คือการดึงค่าจาก server-side ออกไปยังแอพ กรณีนี้จะให้ความสำคัญกับค่าที่ถูกกำหนดจากเงื่อนไขก่อน(value for condition) ถัดมาจึงจะเป็นค่าเริ่มต้น(default value) - แอพพลิเคชัน
คือการรับค่าจาก Remote Config กรณีนี้จะให้ความสำคัญจากค่าที่ดึงมาจาก server-side ที่ได้ activated แล้วเป็นอันดับแรก(ค่าจาก Remote Config Server นั่นเอง) ลำดับถัดมาจะเป็นค่าเริ่มต้นที่อยู่ใน in-app ที่ได้ทำการ setDefaults แล้ว และลำดับสุดท้ายคือกรณที่ไม่ได้กำหนดค่าเริ่มต้นใน default values แอพจะดึงค่า static type value ออกมาเช่น int ก็ดึง 0 หรือ boolean ก็ดึง false เป็นต้น
การพัฒนาเรื่อง Firebase Remote Config จะขอแบ่งออกเป็น 3 parts ดังนี้
- การ Set up Firebase และ Remote Config SDK
- การตั้งค่า และ รับค่า จาก in-app default parameter values
- การตั้งค่า parameter values ที่ server-side
- การดึงค่า parameter values จาก server-side
พร้อมแล้วก็เปิด Android Studio ขึ้นมา โดยจะสร้างโปรเจคใหม่ หรือจะใช้โปรเจคเดิมก็ได้
Part 1 การ Set up Firebase และ Remote Config SDK
ถ้าสร้างโปรเจคใหม่ ให้ไปดูการ Set up Firebase ที่บทความนี้ก่อน
เมื่อ Set up Firebase เรียบร้อยแล้ว ก็ให้เพิ่ม Remote Config SDK ใน build.gradle ของ app-level แล้วกด Sync ก็เป็นอันจบส่วนที่ 1 ละ
dependencies {
compile 'com.google.firebase:firebase-config:11.8.0'
}
Part 2 การตั้งค่า และ รับค่า จาก in-app default parameter values
เรามาเริ่มต้นด้วยการประกาศตัวแปร FirebaseRemoteConfig กันก่อน
private FirebaseRemoteConfig mFirebaseRemoteConfig;
ตามด้วยการประกาศรับค่า Instance ของ FirebaseRemoteConfig
mFirebaseRemoteConfig = FirebaseRemoteConfig.getInstance();
จากนั้นก็ไปสร้างไฟล์ remote_config_defaults.xml ที่โฟลเดอร์ res/xml เพื่อประกาศและเก็บค่าเริ่มต้น โดยมีข้อมูลตัวอย่างดังนี้
- is_promotion_on(มีโปรมั้ย) โดยให้ค่าเริ่มต้นเป็น false
- price โดยให้ค่าเริ่มต้นเป็น 100
- discount(ส่วนลด) โดยให้ค่าเริ่มต้นเป็น 0
เมื่อสร้าง xml เรียบร้อย เราก็มาตั้งค่า config ภายในแอพกัน
mFirebaseRemoteConfig.setDefaults(R.xml.remote_config_defaults);
เมื่อมี Set ก็ต้องมี Get คราวนี้มาลองรับค่าจาก config ดูหน่อย
mFirebaseRemoteConfig.getBoolean("is_promotion_on")
mFirebaseRemoteConfig.getLong("price")
นอกจาก getBoolean และ getLong ในตัวอย่างแล้ว ก็ยังมีประเภท getString, getDouble และ getByteArray อีกนะ
ต่อไปเรามาดูวิธีการดึงค่าจาก Remote Config กันครับ ในกรณีนี้จะให้ดึงค่า config โดยเราจะใช้ mFirebaseRemoteConfig.fetch() ในการดึงค่าจาก Remote Config โดยปกติ .fetch() จะมีเวลา cache อยู่ที่ 43200 วินาที หรือ 12 ชม. แต่เราสามารถระบุตัวเลขวินาทีเองได้ (จะลงรายละเอียดใน part 4) ซึ่งหากดึงสำเร็จแล้ว เราจะใช้คำสั่ง mFirebaseRemoteConfig.activateFetched(); .ในการอัพเดทข้อมูล config เพื่อนำไปใช้งานต่อไป
mFirebaseRemoteConfig.fetch().addOnCompleteListener(
new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
mFirebaseRemoteConfig.activateFetched();
}
displayPrice();
}
}
);
ส่วนการแสดงค่าราคาก็ตาม code ด้านล่างนี้ครับ
private void displayPrice() {
long initialPrice = mFirebaseRemoteConfig.getLong("price");
long finalPrice = initialPrice;
if (mFirebaseRemoteConfig.getBoolean("is_promotion_on")) {
finalPrice = initialPrice - mFirebaseRemoteConfig.getLong("discount");
}
mPriceTextView.setText(getString(R.string.price_prefix, finalPrice + ""));
}
ตัวอย่างการดึงค่าจาก config ซึ่ง is_promotion_on เป็น false ดังนั้น finalPrice ก็คือค่า initialPrice หรือ 100 นั่นเอง
Part 3 การตั้งค่า parameter values ที่ server-side
เริ่มต้นส่วนนี้ก็ไปที่ Firebase Console ก่อนเลย เมื่อเข้ามาแล้วก็คลิกที่เมนู Remote Config ทางด้านซ้ายเบาๆ
ก็จะพบหน้าเชิญชวนให้เรา add parameter ตัวแรก ซึ่งเราก็ใจง่ายอยู่ด้วย กดปุ่ม ADD YOUR FIRST PARAMETER สีฟ้าดิ๊ รอรัย
ต่อไปก็ add parameter และ value ไป โดยอย่าลืมว่า ชื่อต้องตรงกับที่เราตั้งไว้ใน config ภายในแอพนะ ตัวอย่างผมจะ add ไป 2 ตัว เพื่อต้องการ เปิด/ปิด โปรโมชัน และมอบส่วนลดให้ผู้ใช้งาน
ยังไม่พอ ยังไม่พอ ในการเพิ่ม parameter เราสามารถเพิ่ม condition ได้ โดยเราสามารถกำหนดเงื่อนไขได้ตามความต้องการ
สำหรับ Android ตัว App version ให้เราเอาเลขจาก android:versionName มาเป็นตัวพิจารณานะครับ
แถมเรายังเพิ่ม condition ได้หลายตัวใน 1 parameter อีกด้วย จากตัวอย่างจะเห็นว่าเราสามารถกำหนดส่วนลดให้กับผู้ใช้ทั้วไป $15, ผู้ใช้ Android $20 และ ผู้ใช้ในไทยที่ใช้ Android อีก $25 ซึ่งมันยืดหยุ่นมากๆ
Condition นี่หละที่ Remote Config ให้ความสำคัญมากที่สุด
นอกจากนั้น ถ้าใน 1 parameter คุณมีมากกว่า 1 condition แล้ว ตัว Remote Config จะเลือก condition ที่ตรงใจให้ตามลำดับ แบบตรงปุ๊บดึงปั๊บ เมื่อเจอตรงแล้วจะไม่พิจารณา condition ถัดไป ดังนั้น เราจะต้องเรียงลำดับ condition ใหม่ตามความสำคัญได้จาก tab ชื่อ CONDITIONS
เมื่อคุณตั้งค่า parameter จนหนำใจแล้ว ก็ต้องกดปุ่ม PUBLISH CHANGES บริเวณด้านบนขวา ด้วยนะ ไม่งั้นการตั้งค่าด้านบนก็จะไม่สัมฤทธิ์ผล
Part 4 การดึงค่า parameter values จาก server-side
การดึงค่า config จาก server นั้น ปกติ 1 ชม. จะจำกัดได้แค่ 5 ครั้ง ซึ่งเวลาเราพัฒนาอยู่ มันจะต้องเกินกว่า 5 ครั้งแน่นอน ดังนั้นเราจึงจำเป็นต้อง enable developer mode เพื่อที่จะ request ได้เรื่อยๆ โดยแค่วาง source code ด้านล่างนี้ต่อจากการ getInstance ได้เลย
FirebaseRemoteConfigSettings configSettings = new FirebaseRemoteConfigSettings
.Builder()
.setDeveloperModeEnabled(BuildConfig.DEBUG)
.build();
mFirebaseRemoteConfig.setConfigSettings(configSettings);
เรื่อง .fetch() ที่มีค่าเริ่มต้นที่ 12 ชม. นั้นก็นานเกินไป นานเกินกว่าที่เราจะรอได้ในการพัฒนา ดังนั้นให้เพื่อให้เราดึงค่าแบบ realtime ได้ในขณะพัฒนา ให้ตั้งค่า expiration ของ cache ให้เป็น 0 แต่ก็ควรเช็คด้วยว่าเราอยู่ใน developer mode แล้วจึงค่อยดำเนินการ
long cacheExpiration = 3600; // 1 hour in seconds.
if (mFirebaseRemoteConfig.getInfo().getConfigSettings().isDeveloperModeEnabled()) {
cacheExpiration = 0;
}mFirebaseRemoteConfig.fetch(cacheExpiration)...
เรียบร้อยแล้วก็ลองไปปรับค่า is_promotion_on แล้วอย่าลืมกดปุ่ม PUBLISH CHANGES ใน Firebase Console ดูครับ ก็จะเห็นผลทันทีละ
โดย source code ใน MainActity.java ของผมก็เป็นดังนี้
นั่นหละครับ ผมก็เข้าเงื่อนไข เป็นประชากรไทยที่ใช้ Android จึงได้รับส่วนลดไป 25 ทันที ไชโยโห่หิ้ววววว
รู้ไว้ใช่ว่าใส่บ่าแบกหาม
- การ clear app data ไม่สามารถ reset ค่าใน config ได้ หากต้องการเริ่มใหม่โดยสมบูรณ์ต้อง uninstall แล้ว install ใหม่
- ทีม Firebase เขาแนะนำว่าอย่าเก็บข้อมูลความลับทั้งใน parameter และ value ลงใน Remote Config เพราะเขาใช้ method GET ในการรับส่งค่า มันมีโอกาสที่จะโดนถอดรหัสออกไปได้
- ใน Firebase project 1 โปรเจคนั้นมี parameter ได้รวมกันไม่เกิน 2,000 parameters และ condition ไม่เกิน 100 conditions
- ชื่อ parameter 1 ตัว ต้องไม่เกิน 256 characters และความยาวรวมของ parameter ใน Firebase project ต้องไม่เกิน 500,000 characters (จะมีคนตั้งถึงมั้ย)
- ในกรณีที่ไม่สามารถเชื่อมต่ออินเตอร์เน็ตได้ Remote Config จะดึงค่า config จาก cache มาใช้ แต่หากไม่มี cache ก็จะดึงค่าเริ่มต้น config ภายในแอพมาใช้
ก่อนจะจากกันไป ขอฝากใจไว้กับทุกๆท่าน
หากคุณใช้ Firebase Remote Config และ Firebase Analytics มันจะสามารถทำงานแบบ synergy ไปด้วยกัน คล้ายฟงหวิ๋น ขี่พายุทะลุฟ้า โดยมันจะทำให้คุณสามารถเข้าใจลูกค้าคุณมากขึ้น ประเมินค่าได้กับการ config แต่ละครั้งว่าดีหรือไม่ มีผลประทบอย่างไร ด้วยการทำ A/B testing รายละเอียดเพิ่มเติมที่นี่
Firebase Remote Config ถือเป็นบริการที่ดีมากๆอีกตัวหนึ่ง ที่ผมคิดว่าแอพส่วนมากจะมีฟังก์ชันการตั้งค่า config ต่างๆจาก server อยู่แล้ว และจะดีกว่าไหมที่จะให้ Google มาดูแลเรื่องงานเบื้องหลัง infra structure ให้ แถมเตรียม SDK ที่มาให้เรียกใช้ง่ายๆทั้ง Android และ iOS แบบฟรีๆ
ส่วนตัวผมเองก็เปลี่ยน legacy module หลายตัวใน project ที่ทำงานที่ซึ่งมีปัญหาเรื่อง infra structure มาใช้ตัวนี้แล้ว แล้วคุณหละ?…ราตรีสวัสดิ์ พี่น้องชาวไทย