มาใช้ Firebase Dynamic Links เพื่อเปลี่ยน Web User ให้เป็น Mobile User แบบเท่ๆ กันดีกว่า (แบบง่าย)

Siwawes Wongcharoen
Firebase Thailand
Published in
6 min readDec 11, 2016

เรื่องมันมีอยู่ว่า ในตอนนี้ (ปลายปี 2016) พฤติกรรมการใช้งาน Mobile ได้เปลี่ยนไปอย่างเห็นได้ชัด นั่นคือคนแทบจะไม่โหลด App ใหม่กัน ไม่เชื่อลองถามตัวเองดูสิครับว่า App สุดท้ายที่โหลดมาคืออะไร? (ไม่นับเกมนะครับ) พฤติกรรมส่วนใหญ่คือจะเปิด Browser ในมือถือ แล้วก็ Search แล้วก็ทำอะไรๆบน Web แล้วก็จบ

นั่นก็เพราะว่าการโหลด App มันหลายคลิ๊กมากกกกกกกก แล้วยังต้องรอโหลด App มาติดตั้งอีก ถ้าขนาด App มันซักไม่ถึง 10MB ก็ยังพอทน แต่ถ้าขนาดมันมากกว่านั้นก็… (รู้ๆกันเนาะว่า Android ที่ใช้ AOT นี่ติดตั้ง App นานมากกกก และยิ่งฝั่ง iOS นี่ App ตัวนึงเป็น 100MB) แล้วใครจะมานั่งรอล่ะ เพราะเค้าแค่ต้องการอะไรซักอย่าง แบบที่ไม่เสียเวลามาก ก็สู้ทำอะไรๆ ผ่าน Web ไปเลยดีกว่า อาจจะไม่ดีเท่า App แต่ก็ไม่ต้องรอนาน

ฉะนั้น Web จึงเป็นจุดสำคัญจุดหนึ่ง ที่ User เข้าถึงเราได้ และเมื่อ User ใช้ Web เราไปซักพัก จนเกิดความรู้สึกว่า เปลี่ยนไปใช้ App ก็ได้(ฟร๊ะ) จะด้วยเหตุผลว่า Mobile Web นั้นยังไม่ดีเท่า App จริงๆ (หรือเราวางยาไว้ก็แล้วแต่) แล้วฝั่งเราซึ่งเป็นนักพัฒนาจะทำอย่างไร? Link ชี้ไปที่ App Store/Play Store ดีมั้ยนะ ก็คงจะได้ User ไปส่วนหนึ่ง ซึ่งน่าจะจำนวนไม่มากด้วย ก็เพราะว่า User จะเริ่มคิดในใจแล้วว่า เราทำอะไรๆ บน Web ไปตั้งเยอะแล้ว นี่เราต้องไปเริ่มใหม่บน Mobile App อีกหรอ ไม่โหลดดีกว่า (กรณีร้ายแรงที่สุดคือ อาจไม่ใช้ทั้ง Web และ App เราอีกเลย)

ก็น่าจะเห็นปัญหากันแล้วนะครับ ทางแก้ก็คือเราควรจะต้องมีวิธีที่จะนำ User จาก Web ณ จุดที่ User กำลังใช้งานอยู่ ไปส่งบน App ณ จุดๆ เดียวกัน (ถ้าเป็นไปไม่ได้ ก็ให้ใกล้เคียงที่สุดละกัน) เพื่อให้ User รู้สึกแบบว่า Smooth as silk

OK เรารู้สิ่งที่ต้องทำแล้ว แต่จะทำอย่างไรดีล่ะ?

ไม่ต้องห่วงครับ เรื่องนี้ Firebase Dynamic Links ช่วยได้ คือเจ้า Dynamic Links เนี่ย มีสรรพคุณว่า ข้อมูลอะไรที่เราแนบไปกับ Link จะไม่หายไป แม้ว่าจะเป็นการ Install App ว้าวมั้ย (ว้าวสิ) อ่านมาถึงตรงนี้หลายๆ คนน่าจะคุ้นๆ ว่านี่มัน Google Deep links นี่นา ใช่แล้วครับ และ ณ ตอนนี้ Google ก็ได้ Rebrand ให้ใหม่เป็น Firebase Dynamic Links

ซึ่งสิ่งที่เป็น Key สำคัญสุดๆ ที่ Google ภูมิใจนำเสนอคือ

  1. Dynamic Links are durable and survive app installs. อันนี้ชัดเจนนะครับ พูดถึงหลายรอบแล้ว
  2. Dynamically control the user experience. เนื่องจากเราสามารถควบคุมให้ตัว Dynamic Links นั่น ทำงานได้หลายๆ อย่าง ฉะนั้นจึงเหมาะมากที่เราจะนำไปใช้คุมเรื่อง UX ในส่วนของการเปลี่ยนจาก Web User มาเป็น Mobile User
  3. Know which content and campaigns are working. แน่นอนครับว่า มันเป็นส่วนหนึ่งของ Firebase มันจึงมาพร้อมกับความสามารถของ Analytics ที่จะช่วยให้เราเข้าใจ User ของเรามากขึ้น

ในส่วนของการใช้งานนั้น สั้นๆ ก็คือ ด้วยความสามารถของ Dynamic Links เพียงแค่สร้าง Link ขึ้นมา เพียง 1 Link แต่พฤติกรรม การทำงานจะแตกต่างกันไปได้ถึง 3 กรณี ด้วยตัวมันเอง นั่นคือ

  1. บน Android จะไปเปิด App หรือไปที่ Play Store แทนในกรณีที่ยังไม่มี App ในเครื่อง โดยที่ไม่ว่ากรณีใด ข้อมูลที่เราแนบไปกับ Link จะไม่หายไป
  2. บน iOS จะไปเปิด App หรือไปที่ App Store แทนในกรณีที่ยังไม่มี App ในเครื่อง โดยที่ไม่ว่ากรณีใด ข้อมูลที่เราแนบไปกับ Link จะไม่หายไป
  3. บน Desktop จะกลายเป็น Link ปกติธรรมดา

นั่นล่ะครับ ความแจ่มของ Dynamic Links ก็เกริ่นมาพอสมควรแล้วนะครับ มาลงมือทำกันเลยดีกว่า

เตรียมความพร้อม

ก่อนที่จะเริ่มลงมือทำนะครับ ขอให้เตรียมความพร้อมกันก่อนนะครับ โดยใน Blog นี้จะสร้างสถานการณ์จำลองคือ เรามี Web ที่มีโครงสร้างเป็นลักษณะแจ้งข่าวสาร (มีหน้ารวมและหน้ารายละเอียด) ส่วนฝั่งแอพก็มีลักษณะเดียวกันกับ Web นะครับ โดยเราจะฝัง Dynamic Links ไว้ทั้ง 2 หน้า โดยในหน้ารวมข่าว เราจะใช้ Dynamic Links เพื่อโดดเข้า App และในหน้ารายละเอียดจะมี Dynamic Links แบบเฉพาะของแต่ละข่าว เพื่อโดดขึ้นมาบนหน้าข่าวบน App โดยเฉพาะครับ

ต่อมาก็จะเป็นสิ่งที่เราจะต้องใช้ในการทำ Project นี้นั่นก็คือ

  1. มี Firebase Project
  2. มี IDE หรือ Editor ที่สร้าง Web ง่ายๆได้
  3. มี Android Studio (เนื่องจากผู้เขียนมีความลำเอียงมาก จะไม่เขียนวิธีทำบน iOS นะครับ :3 )

ลงมือทำ

ในส่วนนี้จะแบ่งเป็น Part ใหญ่ๆ 3 Parts นะครับ

  1. สร้าง Web
  2. สร้าง Android App
  3. Config Dynamic Links

พร้อมแล้วมาลุยกันเลย

สร้าง Web

ในส่วนนี้เราทำกันง่ายๆ แต่เน้นเข้าใจกันนะครับ ในขั้นนี้แนะนำให้ใช้ Firebase Hosting ทำไปเลยนะครับ
สร้างโครงเว็บขึ้นมาง่ายๆ แค่ 3 หน้านะครับ โดยมีโครงสร้างดังนี้

โดยไฟล์ index.html จะมี Link ชี้ไปที่ไฟล์ news_a.html และ news_b.html ข้างในไฟล์ index.html ก็ตามนี้ได้เลยนะครับ

<p>
<!-- Dynamic Links: 'From web - index' -->
<a href="#">Read in App</a>
<!-- Normal Link: -->
<ul>
<li><a href="news_a.html">News A</a></li>
<li><a href="news_b.html">News B</a></li>
</ul>
</p>

ส่วนในไฟล์ news_a.html และ news_b.html เอาแค่ให้รู้ว่าไฟล์ไหนคือไฟล์ไหนก็พอครับ เสร็จแล้วลองทดสอบดูก่อนว่า ทุกอย่างปกติดีในแบบที่มันควรจะเป็นนะครับ

สร้าง Android App

ในขั้นนี้ก็สร้าง Android Project ตามปกตินะครับ เสร็จแล้วก็จัดการ Integrate Firebase เข้าไปด้วย แต่ตอนทำอย่าลืมใส่ข้อมูลของ Debug signing certificate SHA-1 เข้าไปด้วยนะครับ

ใส่ SHA-1 Signing ตรงนี้

แล้วก็จัดการทำตัวแอพของเราต่อนะครับ เหมือนเดิมนะครับ ทำแบบง่ายๆ แต่เน้นเข้าใจ ทำแค่ 2 Activities พอนะครับ เอาเป็น Main Activity กับ News Activity ละกันนะครับ

Main Activity Design
News Activity Design

จากนั้นจัดการ Bind Widget ต่างๆ รวมถึงทำ Intent ส่งข้อมูลข้าม Activity ให้เรียบร้อย

// MainActivity.java
public enum News {
NEWS_A ("News A"),
NEWS_B ("News B");

public final String val;
News(String val) {
this.val = val;
}
}
private void openNewsActivity(News news) {
Intent intent = new Intent(MainActivity.this, NewsActivity.class);
intent.putExtra(KEY, news);
startActivity(intent);
}
// NewsActivity.java
private void getExtra() {
if (getIntent().hasExtra(MainActivity.KEY)) {
MainActivity.News news = (MainActivity.News) getIntent()
.getSerializableExtra(MainActivity.KEY);
tvNews.setText(news.val);
}
}

เอาประมาณนี้ก่อนนะครับ ทดสอบให้เรียบร้อยก่อนนะครับ ว่ามันทำงานได้ในแบบที่ควรจะเป็น แล้วในขั้นต่อไปเราจะได้มาทำ Dynamic Links กันซักที

หน้าตาประมาณน้ีนะครับ

Config Dynamic Links

เรามาเริ่มกันที่ Firebase Console กันนะครับ ที่เมนูทางซ้ายมือ ให้มองหา Dynamic Links นะครับ จะอยู่ในหัวข้อ GROW

ตอนนี้น่าจะได้หน้าตาแบบนี้กันทุกคนนะครับ

ตรงนี้ต้องขอบอกก่อนนะครับว่า การสร้าง Dynamic Links นั้น เราสามารถทำได้ 2 วิธี คือ สร้างผ่าน Firebase Console และสร้างสดๆ บนเว็บนะครับ เดี๋ยวจะยกตัวอย่างทั้ง 2 วิธีนะครับ เริ่มที่ สร้างผ่าน Firebase Console ก่อนนะครับ เราจะทำ Dynamic Links สำหรับแปะใน Web หน้า Index นะครับ ก็ให้กดปุ่ม GET STARTED ได้เลยนะครับ แล้วใส่ข้อมูลประมาณนี้

ข้อมูลอาจแตกต่างกันได้นะครับ ไม่มีปัญหาอะไร

เมื่อเราสั่งสร้าง Dynamic Links แล้ว หน้า Console จะแสดงข้อมูลของ Dynamic Links ที่เราพึ่งสร้างไป แบบนี้นะครับ

ให้เรา Copy URL นี้ไปแปะในไฟล์ Web index.html นะครับ แล้วหน้าตาจะได้ประมาณนี้

<p>
<!-- Dynamic Links: 'From web - index' -->
<a href="https://s8q9n.app.goo.gl/jdF1">Read in App</a>
<!-- Normal Link: -->
<ul>
<li><a href="news_a.html">News A</a></li>
<li><a href="news_b.html">News B</a></li>
</ul>
</p>

เสร็จแล้วลองทดสอบดูครับ จะพบว่าหากเราลองบน Desktop ก็จะเป็น Link ปกตินะครับ ที่ชี้มาที่ index.html ของเราแต่หากเราลองบน Mobile เราจะพบว่า อ่ะมันเปิดแอพเราขึ้นมาให้เรานี่นา แต่ๆ ยังครับเรายังทำอะไรไม่ครบครับ ต้องไปเติม Code ทางฝั่ง Android อีกนิดนึงครับ

เริ่มจากเพิ่ม Dependency เข้าไปใน Module นะครับ แล้ว Sync ให้เรียบร้อย

compile 'com.google.firebase:firebase-invites:10.0.1'

จากนั้นไปที่ไฟล์ AndroidManifest.xml นะครับ แล้วเพิ่ม Code ส่วนนี้เข้าไปใน MainActivity

<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:host="www.example.com" android:scheme="http"/>
<data android:host="www.example.com" android:scheme="https"/>
</intent-filter>

อย่าลืมเปลี่ยน www.example.com เป็น URL ของเว็บเรานะครับ จากนั้นให้เพิ่ม Code ลงใน MainActivity.java อีกนิดหน่อยนะครับ

// Build GoogleApiClient with AppInvite API for receiving deep links
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this, onConnectionFailedListener)
.addApi(AppInvite.API)
.build();

// Check if this app was launched from a deep link. Setting autoLaunchDeepLink to true
// would automatically launch the deep link if one is found.
boolean autoLaunchDeepLink = false;
AppInvite.AppInviteApi.getInvitation(mGoogleApiClient, this, autoLaunchDeepLink)
.setResultCallback(
new ResultCallback<AppInviteInvitationResult>() {
@SuppressLint("SetTextI18n")
@Override
public void onResult(@NonNull AppInviteInvitationResult result) {
if (result.getStatus().isSuccess()) {
// Extract deep link from Intent
Intent intent = result.getInvitationIntent();
String deepLink = AppInviteReferral.getDeepLink(intent);

// Handle the deep link. For example, open the linked
// content, or apply promotional credit to the user's
// account.

tvActivityTitle.setText("Hello deep link");
Log.d(TAG, "getInvitation: " + deepLink);
} else {
Log.d(TAG, "getInvitation: no deep link found.");
}
}
});

เมื่อวาง Code นี้ไปแล้วนะครับ ให้ทดสอบอีกครั้งนะครับ ด้วยการใช้ผ่าน Mobile นะครับ เมื่อเราคลิ๊กที่ Link ‘Read in App’ ตัวมือถือจะเปิด App ขึ้นมาแล้ว TextView เดิมที่แสดงข้อความว่า MainActivity จะเปลี่ยนเป็น Hello deep link ตามภาพนะครับ

เปลี่ยนเป็น Hello deep link แล้ว

ที่เป็นแบบนี้ ก็เพราะ Code ที่ให้แปะเพิ่มใน MainActivity.java นั้น มีหน้าที่ในการดักข้อมูลที่มาจาก Intent ครับ และเมื่อเราดูใน Logcat เราจะเห็น

ซึ่งนี่ก็คือ Deep Link ที่ได้มากจาก Intent ที่ได้มาจาก Dynamic Links ที่เราดักมาได้ครับ (งงมั้ย) แต่ยังไม่หมดเท่านี้ครับ เราสามารถใส่ Parameter ให้กับ Dynamic Links ได้อีกด้วยนะครับ ซึ่งเราจะสร้าง Dynamic Links แบบที่มี Parameter แบบสดๆ บนเว็บกันนะครับ ซึ่งเราจะทำตาม Pattern นี้กันนะครับ

https://domain/?link=your_deep_link&apn=package_name[&amv=minimum_version][&al=android_link][&afl=fallback_link]

ซึ่งเราจะทำในไฟล์ news_a.html และ news_b.html นะครับ ด้วยการเพิ่ม Link เข้าไปนะครับ

// news_a.html
https://s8q9n.app.goo.gl/?link=https://dynamiclinksdemo-b9f05.firebaseapp.com/?news=news_a&apn=com.puuga.dynamiclinksdemo
// news_b.html
https://s8q9n.app.goo.gl/?link=https://dynamiclinksdemo-b9f05.firebaseapp.com/?news=news_b&apn=com.puuga.dynamiclinksdemo

จากนั้นให้ลองทดสอบอีกครั้งนะครับ ด้วยการใช้ผ่าน Mobile นะครับ แล้วสังเกตุที่ Logcat นะครับ

มาจาก news_a.html
มาจาก news_b.html

มาถึงจุดนี้ ก็น่าจะนึกกันออกแล้วนะครับ ว่าถ้าเราเล่นแร่แปรลิงค์กันดีๆ เนี่ย ส่งมาแบบไหนก็ได้รับแบบนั้นเลยครับ พอมาถึงบน App ก็จัดการกับ String ที่เราได้มา จะทำอะไรต่อจากนั้นก็ไม่ยากละเนาะ

if (deepLink.contains("news_a")) {
openNewsActivity(News.NEWS_A);
} else if (deepLink.contains("news_b")) {
openNewsActivity(News.NEWS_B);
}

เพิ่มเติม

ในส่วนของ intent-filter นั้น เราไม่จำเป็นต้องแปะไว้ใน MainActivity ที่เดียวนะครับ เอาไปแปะกับ Activity ไหนก็ได้ แต่ก็ต้องไปวาง Code สำหรับ Handle ไว้ที่ Activity นั้นด้วยนะครับ

วางโครงสร้างดีๆ คู่กับ Analytics ดีๆ จะเห็นอะไรเยอะแยะไปหมด

วิธีการใช้ Dynamic Links นั้นหลากหลายมาก สามารถเอาไปประยุกต์ใช้ได้หลายวิธีมากๆ เช่น แปะไปกับพวก twitt หรือ ข้อความโฆษณา เพื่อให้โดดเข้า App เราต้องๆได้ เป็นต้น

Code ทั้งหมดดูได้ใน GitHub นะครับ

ก็ครบถ้วนแล้วนะครับ สำหรับการใช้ Firebase Dynamic links แบบง่าย ก็หวังว่าจะเป็นประโยชน์กับผู้อ่านไม่มากก็น้อยนะครับ หากมีประเด็นไหนที่ขาดตกบกพร่องไป หรือมีข้อผิดพลาดประการใด ผู้เขียนขอน้อมรับไว้ ณ ที่นี้ และยินดีปรับปรุงแก้ไขเนื้อหา เพื่อให้เกิดประโยชน์สูงสุดแก่ผู้อ่านทุกท่าน

สวัสดีและขอบคุณครับ

ที่มาและอ้างอิง

https://firebase.google.com/docs/dynamic-links/
https://firebase.google.com/features/dynamic-links/

GitHub

https://github.com/puuga/DynamicLinksDemo-web
https://github.com/puuga/DynamicLinksDemo

--

--