Cloud Firestore

Codelab นี้เป็นส่วนหนึ่งของหลักสูตรการฝึกอบรม Progressive Web App ที่พัฒนาโดยทีมการฝึกอบรมของ Google Developers คุณจะได้ประโยชน์สูงสุดจากหลักสูตรนี้หากคุณทํางานผ่าน Codelab ตามลําดับ

โปรดดูรายละเอียดทั้งหมดเกี่ยวกับหลักสูตรที่หัวข้อการพัฒนา Progressive Web App

สิ่งที่คุณจะได้เรียนรู้

  • วิธีตั้งค่าโปรเจ็กต์ Cloud Firestore บน Firebase
  • การอ่านและเขียนพื้นฐานด้วย Firestore
  • (ไม่บังคับ) วิธีใช้ Cloud Firestore ออฟไลน์

สิ่งที่ควรทราบอยู่แล้ว

  • HTML, CSS และ JavaScript พื้นฐาน
  • คําสัญญา ES2015
  • วิธีเรียกใช้คําสั่งจากบรรทัดคําสั่ง
  • (สําหรับส่วนที่ไม่บังคับ) ความคุ้นเคยกับ Service Worker และ Workbox

สิ่งที่ต้องมี

  • คอมพิวเตอร์ที่มีสิทธิ์เข้าถึงเทอร์มินัล/Shell
  • การเชื่อมต่ออินเทอร์เน็ต
  • เครื่องมือแก้ไขข้อความ
  • โหนดและ npm

ดาวน์โหลดหรือโคลนที่เก็บ pwa-training-labs จาก github และติดตั้ง Node.js เวอร์ชัน LTS

เปิดโฟลเดอร์ firestore-lab/project/ ในเครื่องมือแก้ไขข้อความที่ต้องการ โฟลเดอร์ project/ คือที่ที่คุณจะสร้างห้องทดลอง

สร้างโปรเจ็กต์ Cloud Firestore ใหม่

  1. เปิด Firebase Console และสร้างโปรเจ็กต์ใหม่
  2. ในส่วน Database ให้คลิกลองใช้ Firestore เบต้า
  3. เลือกตัวเลือก "Start ในโหมดทดสอบ"
  4. คลิกเปิดใช้

หมายเหตุ: คุณใช้ทั้ง Cloud Firestore และ Cloud Datastore ในโครงการเดียวกันไม่ได้ ซึ่งอาจส่งผลต่อแอปที่ใช้ App Engine หากโปรเจ็กต์ของคุณใช้ Cloud Datastore อยู่แล้ว ให้ลองใช้ Cloud Firestore กับโปรเจ็กต์อื่น

จากนั้นเพิ่มสคริปต์ต่อไปนี้ลงใน index.html ก่อนแท็กปิด </body>

index.html

<script src="/__/firebase/4.9.0/firebase-app.js"></script>
<script src="/__/firebase/4.9.0/firebase-auth.js"></script>
<script src="/__/firebase/4.9.0/firebase-firestore.js"></script>
<script src="/__/firebase/init.js"></script>

โค้ดนี้จะนําเข้าไลบรารีที่จําเป็นเมื่อโฮสต์แอปโดยใช้โฮสติ้งของ Firebase

คุณจะต้องรับ Firebase CLI เวอร์ชันที่เปิดใช้ Cloud Firestore

เปิดหน้าต่างบรรทัดคําสั่งแล้วเปลี่ยนไดเรกทอรีไปยังโฟลเดอร์ project/

จากนั้นเรียกใช้คําสั่งต่อไปนี้

npm install -g firebase-tools

หลังจากที่ติดตั้งเครื่องมือเสร็จแล้ว ให้ลงชื่อเข้าสู่ระบบเพื่อให้ Firebase CLI โต้ตอบกับโปรเจ็กต์ Firebase ได้

firebase login

จากนั้นเรียกใช้คําสั่งต่อไปนี้ในไดเรกทอรี project/ เพื่อสร้างไฟล์การกําหนดค่าและเริ่มต้นแอป Firebase

firebase init

หลังจากเรียกใช้คําสั่งข้างต้นแล้ว ข้อความแจ้งควรปรากฏในเทอร์มินัล ทําตามข้อความที่ปรากฏด้านล่าง

  1. เลือก Firestore (โดยเลื่อนเคอร์เซอร์ไปที่ตัวเลือก Firestore แล้วกด Space) แล้วกด return
  2. เลือกโปรเจ็กต์ Firebase ที่เพิ่งสร้างและกด return
  3. กด return เพื่อใช้ไฟล์เริ่มต้นสําหรับกฎของ Firestore
  4. กด return เพื่อใช้ไฟล์เริ่มต้นสําหรับดัชนี Firestore

เวลานี้ เราจะเรียกใช้เว็บแอปโดยอัตโนมัติเมื่อทราบว่าจะใช้โปรเจ็กต์ Firebase (และ Firestore) ใด แต่ยังมีขั้นตอนอีก 2-3 อย่างก่อนที่เราจะให้บริการแอปได้

เปิดไฟล์ firebase.json และเพิ่มในการกําหนดค่า hosting ทั้งไฟล์ควรมีลักษณะดังนี้

firebase.json

{
  "hosting": {
    "public": "./",
    "ignore": [
      "firebase.json",
      "database-rules.json",
      "storage.rules",
      "functions"
    ],
    "headers": [
      {
        "source": "**/*.@(js|html)",
        "headers": [
          {
            "key": "Cache-Control",
            "value": "max-age=0"
          }
        ]
      }
    ],
    "rewrites": [
      {
        "source": "**",
        "destination": "/index.html"
      }
    ]
  },
  "firestore": {
    "rules": "firestore.rules",
    "indexes": "firestore.indexes.json"
  }
}

คำอธิบาย

การกําหนดค่า hosting ให้คุณกําหนดวิธีที่ Firebase จะโฮสต์แอป เราจะต้องกําหนดตัวเลือกนี้เพื่อใช้เซิร์ฟเวอร์การพัฒนา Firebase ซึ่งเราจะดําเนินการในขั้นตอนถัดไป โปรดดูข้อมูลอ้างอิงการกําหนดค่าการทําให้ใช้งานได้สําหรับข้อมูลเพิ่มเติม

แม้ว่าการตรวจสอบสิทธิ์จะไม่ใช่เนื้อหาสําคัญของ Codelab แต่สิ่งสําคัญคือต้องมีการตรวจสอบสิทธิ์รูปแบบบางอย่างในแอปของเรา เราจะใช้การเข้าสู่ระบบแบบไม่ระบุตัวตน ซึ่งหมายความว่าผู้ใช้จะเข้าสู่ระบบอย่างเงียบๆ โดยไม่มีการแจ้งเตือน

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

firebase open auth

หรือในคอนโซล Firebase สําหรับโปรเจ็กต์ของคุณ ให้ไปที่พัฒนา > วิธีการตรวจสอบสิทธิ์ &gt

เมื่ออยู่ในหน้านี้ ให้คลิกไม่ระบุชื่อ แล้วคลิกเปิดใช้แล้วคลิกบันทึก

เราพร้อมเริ่มต้นทํางานในแอปของเราแล้ว มาเรียกใช้ในเครื่องด้วยคําสั่ง firebase กันเลย

firebase serve

เปิดเบราว์เซอร์แล้วดู localhost:5000 คุณจะเห็นสําเนา Space Race! ที่เชื่อมต่อกับโปรเจ็กต์ Firebase ของคุณ

โดยแอปได้เชื่อมต่อกับโปรเจ็กต์ของเราโดยอัตโนมัติและได้ลงชื่อเข้าสู่ระบบแบบเงียบๆ ในฐานะผู้ใช้แบบไม่ระบุชื่อ

ในส่วนนี้ เราจะเขียนข้อมูลบางอย่างลงใน Firestore เพื่อให้เราป้อนข้อมูล UI ของแอปได้ โดยใช้คอนโซล Firebase ด้วยตนเอง แต่เราจะดําเนินการในแอปดังกล่าวเพื่อสาธิตการเขียน Firestore พื้นฐานก็ได้

วัตถุโมเดลหลักในแอปของเราเป็นยานอวกาศ ข้อมูล Firestore แทนด้วยเอกสารซึ่งจัดระเบียบเป็นคอลเล็กชันและคอลเล็กชันย่อย ในแอปนี้ เราจะจัดเก็บเรือแต่ละตัวเป็นเอกสารในคอลเล็กชันระดับบนสุดที่เรียกว่า "ships" ดูข้อมูลเพิ่มเติมเกี่ยวกับโมเดลข้อมูล Firestore ได้ในเอกสารประกอบ

ฐานข้อมูล Cloud Firestore ของแอปของเรายังไม่มีข้อมูล ในคอนโซล Firebase สําหรับโปรเจ็กต์ของคุณ ให้ไปที่พัฒนา &gt ฐานข้อมูล แล้วสังเกตว่าฐานข้อมูลว่างเปล่า

มาใช้ฟังก์ชันเพื่อเพิ่มข้อมูลในแอปของเรากัน

เปิด scripts/SpaceRace.Data.js แล้วหาฟังก์ชัน SpaceRace.prototype.addShip แทนที่ฟังก์ชันการทํางานทั้งหมดด้วยโค้ดด้านล่าง

SpaceRace.Data.js

SpaceRace.prototype.addShip = function(data) {
  const collection = firebase.firestore().collection('ships');
  return collection.add(data);
};

รหัสด้านบนจะเพิ่มเอกสารใหม่ลงในคอลเล็กชัน Firestore ของ ships ฟังก์ชันนี้จะอ้างอิงคอลเล็กชัน ships ก่อน จากนั้นตามด้วย add&#39 และ data เอกสาร data มาจากออบเจ็กต์ JavaScript ธรรมดา

กฎความปลอดภัย

เกือบเสร็จแล้ว ก่อนที่จะเขียนเอกสารไปยัง Cloud Firestore เราจําเป็นต้องกําหนดค่ากฎความปลอดภัยของ Firestore กฎเหล่านี้อธิบายถึงส่วนต่างๆ ของฐานข้อมูลที่ควรจะอ่านและเขียนได้ รวมถึงผู้ใช้ที่ต้องการ ในขณะนี้ เราอนุญาตให้ผู้ใช้ที่ได้รับการตรวจสอบสิทธิ์ทั้งหมดอ่านและเขียนไปยังฐานข้อมูลทั้งหมด การอนุญาตนี้เป็นไปได้ไม่มากพอสําหรับแอปเวอร์ชันที่ใช้งานจริง แต่ในระหว่างขั้นตอนการพัฒนา เราอยากให้ใช้อะไรที่ผ่อนคลายมากพอ จึงพบปัญหาการตรวจสอบสิทธิ์อย่างต่อเนื่องขณะทําการทดสอบ

เปิดไฟล์ชื่อ firestore.rules แล้วแทนที่ทั้งไฟล์ด้วยรหัสต่อไปนี้

firestore.rule

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      // Only authenticated users can read or write data
      allow read, write: if request.auth != null;
    }
  }
}

จากนั้นเรียกใช้สิ่งต่อไปนี้ในบรรทัดคําสั่ง

firebase deploy --only firestore:rules

ซึ่งจะทําให้ไฟล์ firestore.rules ใช้งานได้ในโปรเจ็กต์ Firebase ของเรา

อีกวิธีหนึ่งคือเปิดคอนโซล Firebase แล้วไปที่พัฒนา &gt ฐานข้อมูล &gt กฎ และแทนที่กฎเริ่มต้นด้วยกฎใหม่ของเรา

หมายเหตุ: หากต้องการข้อมูลเพิ่มเติมเกี่ยวกับกฎความปลอดภัย โปรดดูเอกสารประกอบของกฎความปลอดภัย

รีเฟรชหน้าและแตะปุ่ม "เพิ่มข้อมูลจําลอง" ปุ่มนี้จะเรียกฟังก์ชัน addMockShips ที่กําหนดใน SpaceRace.Mock.js ซึ่งใช้ฟังก์ชัน addShip ที่เราได้กําหนดไว้ก่อนหน้านี้ addMockShips จะสร้างเอกสารการจัดส่งเป็นกลุ่ม ถึงแม้คุณยังจะไม่เห็นข้อมูลนี้ในแอป เรายังคงต้องเรียกข้อมูลอยู่

จากนั้นไปที่แท็บ Database ในคอนโซล Firebase ตอนนี้คุณควรเห็นรายการใหม่ในคอลเล็กชัน ships (คุณอาจต้องรีเฟรชหน้า)

ยินดีด้วย คุณเพิ่งเขียนข้อมูลลงใน Cloud Firestore จากเว็บแอป ในส่วนถัดไป คุณจะได้ดูวิธีดึงข้อมูลจาก Firestore และแสดงในแอป

ในส่วนนี้ คุณจะได้ดูวิธีดึงข้อมูลจาก Firestore และแสดงข้อมูลในแอป ขั้นตอนสําคัญ 2 ข้อคือการสร้างคําค้นหาและเพิ่ม Listener ของสแนปชอต Listener นี้จะได้รับการแจ้งเตือนด้วยข้อมูลที่มีอยู่ทั้งหมดที่ตรงกับคําค้นหาและรับการอัปเดตแบบเรียลไทม์

มาสร้างคําค้นหาที่แสดงรายการเรือกัน แทนที่เมธอด SpaceRace.prototype.getAllShips() ด้วยโค้ดต่อไปนี้

SpaceRace.Data.js

SpaceRace.prototype.getAllShips = function(render) {
  const query = firebase.firestore()
    .collection('ships')
    .limit(50);
  this.getDocumentsInQuery(query, render);
};

ในตัวอย่างข้อมูลนี้ เราจะสร้างคําค้นหาที่จะเรียกคอลเล็กชันสูงสุด 50 คอลเล็กชันของคอลเล็กชันระดับบนสุดที่ชื่อ "ships" เมื่อเราประกาศการค้นหานี้ เราจะส่งต่อไปยังเมธอด getDocumentsInQuery() ซึ่งมีหน้าที่โหลดและแสดงข้อมูลดังกล่าว วิธีนี้จะใช้ Listener ของสแนปชอต แทนที่เมธอด SpaceRace.prototype.getDocumentsInQuery() ด้วยโค้ดต่อไปนี้

SpaceRace.Data.js

SpaceRace.prototype.getDocumentsInQuery = function(query, render) {
  query.onSnapshot(snapshot => {
    if (!snapshot.size) return render();
    snapshot.docChanges.forEach(change => {
      if (change.type === 'added') {
        render(change.doc);
      }
      else if (change.type === 'removed') {
        document.getElementById(change.doc.id).remove();
      }
    });
  });
};

query.onSnapshot ในโค้ดด้านบนจะทริกเกอร์อาร์กิวเมนต์เรียกกลับทุกครั้งที่มีการเปลี่ยนผลลัพธ์ของคําค้นหา เมื่อเรียกใช้ครั้งแรก การเรียกกลับด้วยชุดผลการค้นหาทั้งหมดซึ่งเป็นคอลเล็กชัน ships ที่สมบูรณ์จาก Firestore การเปลี่ยนแปลงเอกสารแต่ละรายการจะมีพร็อพเพอร์ตี้ type ซึ่งแสดงว่ามีการเปลี่ยนแปลงอย่างไร หากเอกสารคือ added ระบบจะส่งเอกสารไปยังฟังก์ชัน render หากเป็นเอกสาร removed ระบบจะนําบัตรที่เกี่ยวข้องออกจาก DOM

ตอนนี้เรานําวิธีเรียกข้อมูลทั้ง 2 วิธีมาใช้แล้ว ให้รีเฟรชแอปและตรวจสอบว่าข้อมูลเรือที่เราเพิ่มไปยัง Cloud Firestore (และดูในคอนโซล Firestore) แสดงอยู่ในแอป หากดําเนินการส่วนนี้สําเร็จแล้ว แสดงว่าแอปกําลังอ่านและเขียนข้อมูลด้วย Cloud Firestore

ลองเพิ่มเรือที่กําหนดเองโดยกรอกแบบฟอร์มของแอปแล้วคลิก "Add" เมื่อรายการเรือของคุณมีการเปลี่ยนแปลง Listener นี้จะอัปเดตต่อไปโดยอัตโนมัติ ตอนนี้ให้ลองไปที่คอนโซล Firebase แล้วเพิ่มต้นทางการจัดส่งด้วยตนเอง แล้วคุณจะเห็นเครื่องมือนี้แสดงขึ้นบนเว็บไซต์ทันที

หมายเหตุ: คุณยังดึงข้อมูลเอกสารจาก Firestore 1 ครั้งแทนการฟังการอัปเดตแบบเรียลไทม์ได้โดยใช้เมธอด Query.get()

มาเขียนฟังก์ชันเพื่อลบเรือบางประเภทออกจากคอลเล็กชันกัน

แทนที่เมธอด SpaceRace.prototype.deleteShip() ใน SpaceRace.Data.js ด้วยรหัสต่อไปนี้

SpaceRace.Data.js

SpaceRace.prototype.deleteShip = function(id) {
  const collection = firebase.firestore().collection('ships');
  return collection.doc(id).delete()
    .catch(function(error) {
      console.error('Error removing document: ', error);
    });
};

เมื่อดําเนินการแล้ว คุณจะลบเรือที่เฉพาะเจาะจงได้โดยคลิก ""X" ที่มุมขวาบนของการ์ด "เรือ" บันทึกไฟล์ รีเฟรชแอป และลองลบเรือ

นอกจากนี้ Cloud Firestore ยังรองรับการคงข้อมูลออฟไลน์ ซึ่งจะแคชสําเนาข้อมูลของแอปของคุณเองที่แก้ไขได้เมื่อผู้ใช้ออฟไลน์ และซิงค์เมื่อคืนค่าการเชื่อมต่อ เมื่อรวมกับ Service Worker แล้ว เราจะอัปเดตแอปเพื่อให้ทํางานแบบออฟไลน์ได้

สร้างไฟล์ชื่อ sw.js ที่รูทของไดเรกทอรี project/ ด้วยรหัสต่อไปนี้

importScripts('https://storage.googleapis.com/workbox-cdn/releases/3.4.1/workbox-sw.js');

if (workbox) {

  // Pre-cache HTML, CSS, and image assets
  workbox.precaching.precacheAndRoute([
    {
      "url": "index.html",
      "revision": "a7a5b45e7a48ecf2cb10fd8bddf70342"
    },
    {
      "url": "style/main.css",
      "revision": "7ca18ea2f5608b3c3f67339a57a4fc8e"
    },
    {
      "url": "images/delete.svg",
      "revision": "840ae217e9fe8c73c6d76286aefef63f"
    },
    {
      "url": "images/rocket-form.svg",
      "revision": "6bcd12b01e14547c1f9e0069c3da5f0d"
    },
    {
      "url": "images/rocket-icon.png",
      "revision": "f61c19851368484e8cb7efebf4d26a77"
    },
    {
      "url": "images/rocket.svg",
      "revision": "19df337059a0d6420869bcd20bdc6fab"
    },
    {
      "url": "images/ship_0.jpg",
      "revision": "58bb2ed6c80b6ca362c18515f07f2aee"
    },
    {
      "url": "images/ship_1.jpg",
      "revision": "94895878d03c00fae4f19583efb53ad2"
    },
    {
      "url": "images/ship_2.jpg",
      "revision": "992f720b3d4d3d21c83a7e71057effc9"
    },
    {
      "url": "images/ship_3.jpg",
      "revision": "06c2a683898186f728c564c9e518d16c"
    },
    {
      "url": "images/ship_4.jpg",
      "revision": "04673dcead6d46a65fdfb7c78984afd8"
    },
    {
      "url": "images/ship_5.jpg",
      "revision": "d08b0352c8971af5f881dcde0542ed97"
    },
    {
      "url": "images/ship_6.jpg",
      "revision": "0ccd8c0c257264e0496eed72d4beb936"
    },
    {
      "url": "images/ship_7.jpg",
      "revision": "af52e423fd57b2205c95bd308d50663e"
    },
    {
      "url": "images/ship_8.jpg",
      "revision": "00a5102cdfac3dbc041fb5b286e6b0e7"
    },
    {
      "url": "images/ship_9.jpg",
      "revision": "4b57c477216cb8c106b0c09ee9376249"
    }
  ]);

  // Force update of newest service worker
  workbox.skipWaiting();
  workbox.clientsClaim();

  // Google Fonts
  workbox.routing.registerRoute(
    new RegExp('https://fonts.(?:googleapis|gstatic).com/(.*)'),
    workbox.strategies.staleWhileRevalidate()
  );

  // Material Design & navigation library
  workbox.routing.registerRoute(
    new RegExp('https://unpkg.com/(.*)'),
    workbox.strategies.staleWhileRevalidate()
  );

  // App scripts
  workbox.routing.registerRoute(
    new RegExp('/scripts/(.*)'),
    workbox.strategies.staleWhileRevalidate()
  );

  // Firebase libraries
  workbox.routing.registerRoute(
    new RegExp('http://localhost:5000/__/firebase'),
    workbox.strategies.staleWhileRevalidate()
  );

} else {
  console.log(`Workbox didn't load 😬`);
}

จากนั้นเพิ่มสคริปต์ก่อนแท็กปิด body ใน index.html เพื่อลงทะเบียน Service Worker ที่เพิ่งสร้าง

index.html

  <script>
    if ('serviceWorker' in navigator) {
      window.addEventListener('load', () => {
        navigator.serviceWorker.register('/sw.js')
          .then(reg => {
            console.log('Service worker registered! 😎', reg);
          })
          .catch(err => {
            console.log('😥 Registration failed: ', err);
          });
      });
    }
  </script>

สุดท้าย แทนที่ฟังก์ชัน SpaceRace ใน SpaceRace.js ด้วยรหัสต่อไปนี้ ซึ่งเรียกใช้เมธอด enablePersistence:

สคริปต์/Spacerace.js

function SpaceRace() {
  firebase.auth().signInAnonymously().then(() => {
    firebase.firestore().enablePersistence()
      .then(() => {
        this.initTemplates();
        this.initRouter();
      });
  }).catch(err => {
    console.log(err);
  });
}

รีเฟรชแอปในเบราว์เซอร์ 2 ครั้ง (1 ครั้งเพื่อติดตั้ง Service Worker และ 1 ครั้งเพื่อแคชเนื้อหาเว็บไซต์) จากนั้นปิดใช้งานเซิร์ฟเวอร์ภายในของ Firebase ด้วย Ctrl + c และปิด Wi-Fi ของคอมพิวเตอร์ โหลดเว็บแอปซ้ําและสังเกตว่าโหลดแบบออฟไลน์ ลองเพิ่มเรือใหม่และลบเรือที่มีอยู่ คืนค่าการเชื่อมต่อ Wi-Fi และรีสตาร์ทเซิร์ฟเวอร์ด้วย firebase serve จากนั้นโหลดหน้าเว็บซ้ําและสังเกตว่าการเปลี่ยนแปลงออฟไลน์ทั้งหมดยังคงอยู่

หมายเหตุ: Firestore ที่เปิดใช้แบบออฟไลน์อาจไม่ทํางานตามที่คาดไว้ในกรณีที่มีหลายแท็บเปิดอยู่ อย่าลืมทดสอบแอปในแท็บเดียว ดูข้อมูลเพิ่มเติมได้ในเอกสาร

คำอธิบาย

Service Worker ที่ระบุใช้ Workbox เพื่อแคชเนื้อหาของเว็บไซต์ เช่น HTML, CSS และ JavaScript ไว้ในอุปกรณ์ วิธีนี้ช่วยให้แอปของเราโหลด (เร็วมาก) แม้จะไม่สามารถดึงทรัพยากรเหล่านี้จากเครือข่ายได้

นอกเหนือจากการใช้ Service Worker API สําหรับทรัพยากรแบบออฟไลน์แล้ว เรายังเพิ่มเมธอด enablePersistence ลงในฟังก์ชันที่จะเริ่มต้นแอปของเราซึ่งก็คือ SpaceRace การดําเนินการนี้จะกําหนดค่าอินสแตนซ์ Cloud Firestore เพื่อแคชสําเนาข้อมูล Firestore ภายในเครื่อง การใช้ข้อมูลในพื้นที่มีข้อดีที่สําคัญ 2 ประการดังนี้

  1. ข้อมูลของเราโหลดได้รวดเร็วมาก เพราะไม่จําเป็นต้องรอเครือข่าย
  2. แอปสามารถเข้าถึงและแก้ไขข้อมูลได้แม้ขณะออฟไลน์ และซิงค์การเปลี่ยนแปลงเมื่อการเชื่อมต่อกลับมา

โปรดดูเอกสารเพื่อดูข้อมูลเพิ่มเติมเกี่ยวกับการคงสถานะออฟไลน์ใน Firestore รวมถึงความแตกต่างที่สําคัญเกี่ยวกับการรักษาความปลอดภัย

ใน Codelab นี้ คุณได้ทราบวิธีอ่านและเขียนใน Firestore พื้นฐาน รวมถึงวิธีรักษาความปลอดภัยของข้อมูลด้วยกฎความปลอดภัย และคุณได้เรียนรู้วิธีใช้ Cloud Firestore และ Service Worker เพื่อเปิดใช้ฟังก์ชันการทํางานแบบออฟไลน์แล้ว

หากต้องการดูข้อมูลเพิ่มเติมเกี่ยวกับ Firestore โปรดไปที่แหล่งข้อมูลต่อไปนี้

ดู Codelab ทั้งหมดในหลักสูตรการฝึกอบรม PWA ที่หัวข้อยินดีต้อนรับ Codelab ของหลักสูตร/