আপনার ক্লাউড ফায়ারস্টোর নিরাপত্তা নিয়ম পরীক্ষা করুন

আপনার অ্যাপ তৈরি করার সময়, আপনি আপনার Cloud Firestore ডেটাবেসের অ্যাক্সেস সুরক্ষিত করতে চাইতে পারেন। তবে, অ্যাপটি চালু করার আগে, আপনার আরও সূক্ষ্ম Cloud Firestore Security Rules প্রয়োজন হবে। Cloud Firestore এমুলেটরের সাহায্যে, আপনার অ্যাপের সাধারণ ফিচার ও আচরণের প্রোটোটাইপিং এবং টেস্টিং করার পাশাপাশি, আপনি ইউনিট টেস্টও লিখতে পারেন যা আপনার Cloud Firestore Security Rules এর আচরণ পরীক্ষা করে।

কুইকস্টার্ট

সহজ নিয়মসহ কয়েকটি প্রাথমিক টেস্ট কেসের জন্য কুইকস্টার্ট স্যাম্পলটি ব্যবহার করে দেখুন।

Cloud Firestore Security Rules বুঝুন

মোবাইল এবং ওয়েব ক্লায়েন্ট লাইব্রেরি ব্যবহার করার সময় সার্ভারবিহীন প্রমাণীকরণ, অনুমোদন এবং ডেটা যাচাইকরণের জন্য Firebase Authentication এবং Cloud Firestore Security Rules প্রয়োগ করুন।

Cloud Firestore Security Rules দুটি অংশ রয়েছে:

  1. একটি match স্টেটমেন্ট যা আপনার ডাটাবেসে থাকা ডকুমেন্টগুলো শনাক্ত করে।
  2. একটি allow এক্সপ্রেশন যা ওই ডকুমেন্টগুলোতে অ্যাক্সেস নিয়ন্ত্রণ করে।

Firebase Authentication ব্যবহারকারীদের পরিচয়পত্র যাচাই করে এবং ব্যবহারকারী-ভিত্তিক ও ভূমিকা-ভিত্তিক অ্যাক্সেস সিস্টেমের ভিত্তি প্রদান করে।

Cloud Firestore মোবাইল/ওয়েব ক্লায়েন্ট লাইব্রেরি থেকে করা প্রতিটি ডাটাবেস অনুরোধ, কোনো ডেটা পড়া বা লেখার আগে আপনার নিরাপত্তা নিয়ম অনুসারে মূল্যায়ন করা হয়। যদি নিয়মগুলো নির্দিষ্ট ডকুমেন্ট পাথগুলোর কোনোটিতে অ্যাক্সেস প্রত্যাখ্যান করে, তাহলে সম্পূর্ণ অনুরোধটি ব্যর্থ হয়।

Cloud Firestore Security Rules সম্পর্কে আরও জানতে Cloud Firestore Security Rules দিয়ে শুরু করুন" অংশটি দেখুন।

এমুলেটর ইনস্টল করুন

Cloud Firestore এমুলেটর ইনস্টল করতে, Firebase সিএলআই (Firebase CLI) ব্যবহার করুন এবং নিচের কমান্ডটি চালান:

firebase setup:emulators:firestore

এমুলেটরটি চালান

প্রথমে আপনার ওয়ার্কিং ডিরেক্টরিতে একটি ফায়ারবেস প্রজেক্ট ইনিশিয়ালাইজ করুন। ফায়ারবেস সিএলআই (Firebase CLI) ব্যবহার করার সময় এটি একটি সাধারণ প্রথম পদক্ষেপ।

firebase init

নিম্নলিখিত কমান্ডটি ব্যবহার করে এমুলেটরটি চালু করুন। আপনি প্রসেসটি বন্ধ না করা পর্যন্ত এমুলেটরটি চলতে থাকবে:

firebase emulators:start --only firestore

অনেক ক্ষেত্রে আপনি এমুলেটর চালু করে একটি টেস্ট স্যুট চালাতে চান এবং টেস্টগুলো শেষ হলে এমুলেটরটি বন্ধ করে দিতে চান। আপনি emulators:exec কমান্ডটি ব্যবহার করে সহজেই এটি করতে পারেন:

firebase emulators:exec --only firestore "./my-test-script.sh"

চালু করার সময় এমুলেটরটি ডিফল্ট পোর্টে (8080) চলার চেষ্টা করবে। আপনি আপনার firebase.json ফাইলের "emulators" অংশটি পরিবর্তন করে এমুলেটর পোর্ট পরিবর্তন করতে পারেন:

{
  // ...
  "emulators": {
    "firestore": {
      "port": "YOUR_PORT"
    }
  }
}

Before you run the emulator

এমুলেটর ব্যবহার শুরু করার আগে নিম্নলিখিত বিষয়গুলো মনে রাখবেন:

  • এমুলেটরটি প্রথমে আপনার firebase.json ফাইলের firestore.rules ফিল্ডে নির্দিষ্ট করা নিয়মগুলো লোড করবে। এটি আপনার Cloud Firestore Security Rules ধারণকারী একটি স্থানীয় ফাইলের নাম আশা করে এবং সেই নিয়মগুলো সমস্ত প্রোজেক্টে প্রয়োগ করে। যদি আপনি স্থানীয় ফাইলের পাথ প্রদান না করেন অথবা নিচে বর্ণিত loadFirestoreRules মেথডটি ব্যবহার না করেন, তাহলে এমুলেটরটি সমস্ত প্রোজেক্টকে ওপেন রুলসযুক্ত হিসেবে গণ্য করবে।
  • যদিও বেশিরভাগ Firebase SDK সরাসরি এমুলেটরগুলির সাথে কাজ করে, শুধুমাত্র @firebase/rules-unit-testing লাইব্রেরিটি সিকিউরিটি রুলস-এ auth মক করা সমর্থন করে, যা ইউনিট টেস্টকে অনেক সহজ করে তোলে। এছাড়াও, লাইব্রেরিটি সমস্ত ডেটা মুছে ফেলার মতো কয়েকটি এমুলেটর-নির্দিষ্ট বৈশিষ্ট্য সমর্থন করে, যা নিচে তালিকাভুক্ত করা হলো।
  • এমুলেটরগুলো ক্লায়েন্ট SDK-এর মাধ্যমে সরবরাহ করা প্রোডাকশন Firebase Auth টোকেনও গ্রহণ করবে এবং সেই অনুযায়ী নিয়মগুলো মূল্যায়ন করবে, যা ইন্টিগ্রেশন এবং ম্যানুয়াল টেস্টের ক্ষেত্রে আপনার অ্যাপ্লিকেশনকে সরাসরি এমুলেটরগুলোর সাথে সংযুক্ত করার সুযোগ দেয়।

স্থানীয় ইউনিট পরীক্ষা চালান

v9 জাভাস্ক্রিপ্ট SDK দিয়ে স্থানীয় ইউনিট টেস্ট চালান

ফায়ারবেস তার সংস্করণ ৯ জাভাস্ক্রিপ্ট এসডিকে এবং সংস্করণ ৮ এসডিকে উভয়ের সাথেই একটি সিকিউরিটি রুলস ইউনিট টেস্টিং লাইব্রেরি সরবরাহ করে। লাইব্রেরিগুলোর এপিআই (API) উল্লেখযোগ্যভাবে ভিন্ন। আমরা সংস্করণ ৯ টেস্টিং লাইব্রেরিটি ব্যবহারের পরামর্শ দিই, যা আরও সুবিন্যস্ত এবং এমুলেটরের সাথে সংযোগ স্থাপনের জন্য কম সেটআপের প্রয়োজন হয়, ফলে প্রোডাকশন রিসোর্সের অনিচ্ছাকৃত ব্যবহার নিরাপদে এড়ানো যায়। পূর্ববর্তী সংস্করণের সাথে সামঞ্জস্যতা (backwards compatibility) বজায় রাখার জন্য, আমরা সংস্করণ ৮ টেস্টিং লাইব্রেরিটিও সরবরাহ করে চলেছি।

স্থানীয়ভাবে চলমান এমুলেটরের সাথে ইন্টারঅ্যাক্ট করার জন্য @firebase/rules-unit-testing মডিউলটি ব্যবহার করুন। যদি আপনি টাইমআউট বা ECONNREFUSED এরর পান, তবে এমুলেটরটি আসলেই চলছে কিনা তা পুনরায় যাচাই করুন।

আমরা Node.js-এর একটি সাম্প্রতিক সংস্করণ ব্যবহার করার জন্য দৃঢ়ভাবে সুপারিশ করছি, যাতে আপনি async/await নোটেশন ব্যবহার করতে পারেন। আপনি যে আচরণগুলো পরীক্ষা করতে চাইতে পারেন তার প্রায় সবই অ্যাসিঙ্ক্রোনাস ফাংশনের সাথে জড়িত, এবং টেস্টিং মডিউলটি প্রমিজ-ভিত্তিক কোডের সাথে কাজ করার জন্য ডিজাইন করা হয়েছে।

v9 Rules ইউনিট টেস্টিং লাইব্রেরিটি এমুলেটরগুলো সম্পর্কে সর্বদা অবগত থাকে এবং আপনার প্রোডাকশন রিসোর্সকে কখনো স্পর্শ করে না।

আপনি v9 মডিউলার ইম্পোর্ট স্টেটমেন্ট ব্যবহার করে লাইব্রেরিটি ইম্পোর্ট করতে পারেন। উদাহরণস্বরূপ:

import {
  assertFails,
  assertSucceeds,
  initializeTestEnvironment
} from "@firebase/rules-unit-testing"

// Use `const { … } = require("@firebase/rules-unit-testing")` if imports are not supported
// Or we suggest `const testing = require("@firebase/rules-unit-testing")` if necessary.

একবার ইম্পোর্ট করা হয়ে গেলে, ইউনিট টেস্ট বাস্তবায়ন করতে নিম্নলিখিত ধাপগুলো অনুসরণ করতে হয়:

  • initializeTestEnvironment কল করার মাধ্যমে একটি RulesTestEnvironment তৈরি এবং কনফিগার করা।
  • RulesTestEnvironment.withSecurityRulesDisabled একটি সুবিধাজনক পদ্ধতি ব্যবহার করে, যা আপনাকে সাময়িকভাবে নিয়মগুলো এড়িয়ে যেতে দেয়, নিয়মগুলো সক্রিয় না করেই পরীক্ষার ডেটা সেট আপ করা।
  • টেস্ট ডেটা এবং এনভায়রনমেন্ট পরিষ্কার করার জন্য টেস্ট স্যুট এবং প্রতিটি টেস্টের জন্য বিফোর/আফটার হুক সেট আপ করা, যেমন RulesTestEnvironment.cleanup() বা RulesTestEnvironment.clearFirestore()
  • RulesTestEnvironment.authenticatedContext এবং RulesTestEnvironment.unauthenticatedContext ব্যবহার করে প্রমাণীকরণ অবস্থা অনুকরণকারী টেস্ট কেস বাস্তবায়ন করা।

Common methods and utility functions

এছাড়াও v9 SDK-তে এমুলেটর-নির্দিষ্ট পরীক্ষার পদ্ধতিগুলো দেখুন।

initializeTestEnvironment() => RulesTestEnvironment

এই ফাংশনটি রুলস ইউনিট টেস্টিং-এর জন্য একটি টেস্ট এনভায়রনমেন্ট চালু করে। টেস্ট সেটআপের জন্য প্রথমে এই ফাংশনটি কল করুন। সফলভাবে কার্য সম্পাদনের জন্য এমুলেটরগুলো চালু থাকা আবশ্যক।

ফাংশনটি একটি ঐচ্ছিক অবজেক্ট গ্রহণ করে যা একটি TestEnvironmentConfig নির্ধারণ করে, এবং এতে একটি প্রজেক্ট আইডি ও এমুলেটর কনফিগারেশন সেটিংস থাকতে পারে।

let testEnv = await initializeTestEnvironment({
  projectId: "demo-project-1234",
  firestore: {
    rules: fs.readFileSync("firestore.rules", "utf8"),
  },
});

RulesTestEnvironment.authenticatedContext({ user_id: string, tokenOptions?: TokenOptions }) => RulesTestContext

এই মেথডটি একটি RulesTestContext তৈরি করে, যা একজন প্রমাণীকৃত Authentication ব্যবহারকারীর মতো আচরণ করে। ফেরত আসা কনটেক্সটের মাধ্যমে তৈরি করা রিকোয়েস্টগুলোর সাথে একটি মক Authentication টোকেন সংযুক্ত থাকবে। ঐচ্ছিকভাবে, Authentication টোকেন পেলোডের জন্য কাস্টম ক্লেইম বা ওভাররাইড সংজ্ঞায়িত করে এমন একটি অবজেক্ট পাস করতে পারেন।

আপনার টেস্টে ফেরত আসা টেস্ট কনটেক্সট অবজেক্টটি ব্যবহার করে initializeTestEnvironment দিয়ে কনফিগার করা এমুলেটর ইনস্ট্যান্সগুলো সহ কনফিগার করা যেকোনো এমুলেটর ইনস্ট্যান্স অ্যাক্সেস করুন।

// Assuming a Firestore app and the Firestore emulator for this example
import { setDoc } from "firebase/firestore";

const alice = testEnv.authenticatedContext("alice", {  });
// Use the Firestore instance associated with this context
await assertSucceeds(setDoc(alice.firestore().doc('/users/alice'), { ... });

RulesTestEnvironment.unauthenticatedContext() => RulesTestContext

এই মেথডটি একটি RulesTestContext তৈরি করে, যা এমন একজন ক্লায়েন্টের মতো আচরণ করে যে অথেনটিকেশনের মাধ্যমে লগ ইন করেনি। ফেরত আসা কনটেক্সটের মাধ্যমে তৈরি করা রিকোয়েস্টগুলোর সাথে ফায়ারবেস অথেনটিক টোকেন সংযুক্ত থাকবে না।

আপনার টেস্টে ফেরত আসা টেস্ট কনটেক্সট অবজেক্টটি ব্যবহার করে initializeTestEnvironment দিয়ে কনফিগার করা এমুলেটর ইনস্ট্যান্সগুলো সহ কনফিগার করা যেকোনো এমুলেটর ইনস্ট্যান্স অ্যাক্সেস করুন।

// Assuming a Cloud Storage app and the Storage emulator for this example
import { getStorage, ref, deleteObject } from "firebase/storage";

const alice = testEnv.unauthenticatedContext();

// Use the Cloud Storage instance associated with this context
const desertRef = ref(alice.storage(), 'images/desert.jpg');
await assertSucceeds(deleteObject(desertRef));

RulesTestEnvironment.withSecurityRulesDisabled()

এমন একটি কনটেক্সট ব্যবহার করে একটি টেস্ট সেটআপ ফাংশন চালান, যা সিকিউরিটি রুলস নিষ্ক্রিয় থাকার মতো আচরণ করে।

এই মেথডটি একটি কলব্যাক ফাংশন গ্রহণ করে, যা সিকিউরিটি-রুল-বাইপাসিং কনটেক্সটটি নেয় এবং একটি প্রমিজ রিটার্ন করে। প্রমিজটি রিজলভ বা রিজেক্ট হলে কনটেক্সটটি ডেস্ট্রয় হয়ে যাবে।

RulesTestEnvironment.cleanup()

এই পদ্ধতিটি টেস্ট এনভায়রনমেন্টে তৈরি হওয়া সমস্ত RulesTestContexts ধ্বংস করে এবং অন্তর্নিহিত রিসোর্সগুলো পরিষ্কার করে, যার ফলে সুষ্ঠুভাবে প্রস্থান করা যায়।

এই পদ্ধতি এমুলেটরগুলির অবস্থা কোনোভাবেই পরিবর্তন করে না। টেস্টগুলির মধ্যে ডেটা রিসেট করতে, অ্যাপ্লিকেশন এমুলেটর-নির্দিষ্ট ক্লিয়ার ডেটা পদ্ধতিটি ব্যবহার করুন।

assertSucceeds(pr: Promise<any>)) => Promise<any>

This is a test case utility function.

ফাংশনটি এই মর্মে নিশ্চয়তা প্রদান করে যে, একটি এমুলেটর অপারেশনকে আবৃতকারী সরবরাহকৃত প্রমিসটি কোনো নিরাপত্তা বিধি লঙ্ঘন ছাড়াই সমাধান করা হবে।

await assertSucceeds(setDoc(alice.firestore(), '/users/alice'), { ... });

assertFails(pr: Promise<any>)) => Promise<any>

এটি একটি টেস্ট কেস ইউটিলিটি ফাংশন।

ফাংশনটি দাবি করে যে, একটি এমুলেটর অপারেশনকে আবৃত করে থাকা সরবরাহকৃত প্রমিসটি সিকিউরিটি রুলস লঙ্ঘনের কারণে প্রত্যাখ্যাত হবে।

await assertFails(setDoc(alice.firestore(), '/users/bob'), { ... });

Emulator-specific methods

এছাড়াও v9 SDK-তে সাধারণ পরীক্ষার পদ্ধতি এবং ইউটিলিটি ফাংশনগুলো দেখুন।

RulesTestEnvironment.clearFirestore() => Promise<void>

এই পদ্ধতিটি ফায়ারস্টোর এমুলেটরের জন্য কনফিগার করা projectId এর অন্তর্গত ফায়ারস্টোর ডেটাবেসের ডেটা মুছে ফেলে।

RulesTestContext.firestore(settings?: Firestore.FirestoreSettings) => Firestore;

এই মেথডটি এই টেস্ট কনটেক্সটের জন্য একটি ফায়ারস্টোর ইনস্ট্যান্স সংগ্রহ করে। ফেরত আসা ফায়ারবেস জেএস ক্লায়েন্ট এসডিকে ইনস্ট্যান্সটি ক্লায়েন্ট এসডিকে এপিআই (v9 মডিউলার বা v9 কম্প্যাট) এর সাথে ব্যবহার করা যেতে পারে।

নিয়ম মূল্যায়ন কল্পনা করুন

Cloud Firestore এমুলেটর আপনাকে এমুলেটর স্যুট UI-তে ক্লায়েন্ট অনুরোধগুলি দেখতে দেয়, যার মধ্যে ফায়ারবেস নিরাপত্তা নিয়মগুলির মূল্যায়ন ট্রেসিংও অন্তর্ভুক্ত।

প্রতিটি অনুরোধের বিস্তারিত মূল্যায়ন ক্রম দেখতে Firestore > Requests ট্যাবটি খুলুন।

ফায়ারস্টোর এমুলেটর রিকোয়েস্ট মনিটর নিরাপত্তা নিয়ম মূল্যায়ন দেখাচ্ছে

Generate test reports

একাধিক পরীক্ষা চালানোর পর, আপনি টেস্ট কভারেজ রিপোর্টগুলো দেখতে পারবেন, যেখানে দেখানো হবে আপনার প্রতিটি নিরাপত্তা নিয়ম কীভাবে মূল্যায়ন করা হয়েছে।

রিপোর্টগুলো পেতে, এমুলেটরটি চালু থাকা অবস্থায় এর একটি এক্সপোজড এন্ডপয়েন্টে কোয়েরি করুন। ব্রাউজার-বান্ধব সংস্করণের জন্য, নিম্নলিখিত URL-টি ব্যবহার করুন:

http://localhost:8080/emulator/v1/projects/<project_id>:ruleCoverage.html

এটি আপনার নিয়মগুলোকে এক্সপ্রেশন এবং সাব-এক্সপ্রেশনে বিভক্ত করে, যেগুলোর উপর মাউস রাখলে আপনি আরও তথ্য জানতে পারবেন, যার মধ্যে ইভ্যালুয়েশনের সংখ্যা এবং ফেরত আসা মান অন্তর্ভুক্ত। এই ডেটার র JSON সংস্করণের জন্য, আপনার কোয়েরিতে নিম্নলিখিত URL-টি অন্তর্ভুক্ত করুন:

http://localhost:8080/emulator/v1/projects/<project_id>:ruleCoverage

Differences between the emulator and production

  1. আপনাকে আলাদাভাবে কোনো Cloud Firestore প্রজেক্ট তৈরি করতে হবে না। এমুলেটরটি অ্যাক্সেস করা যেকোনো ইনস্ট্যান্স স্বয়ংক্রিয়ভাবে তৈরি করে নেয়।
  2. Cloud Firestore এমুলেটর সাধারণ Firebase Authentication ফ্লো-এর সাথে কাজ করে না। এর পরিবর্তে, ফায়ারবেস টেস্ট এসডিকে-তে, আমরা rules-unit-testing লাইব্রেরিতে initializeTestApp() মেথডটি দিয়েছি, যা একটি auth ফিল্ড গ্রহণ করে। এই মেথড ব্যবহার করে তৈরি করা ফায়ারবেস হ্যান্ডেলটি এমনভাবে আচরণ করবে যেন এটি আপনার দেওয়া যেকোনো এনটিটি হিসাবে সফলভাবে অথেনটিকেটেড হয়েছে। আপনি যদি null পাস করেন, তবে এটি একজন আনঅথেনটিকেটেড ব্যবহারকারীর মতো আচরণ করবে (উদাহরণস্বরূপ, auth != null হলে রুলগুলো ব্যর্থ হবে)।

Troubleshoot known issues

Cloud Firestore এমুলেটর ব্যবহার করার সময়, আপনি নিম্নলিখিত পরিচিত সমস্যাগুলির সম্মুখীন হতে পারেন। আপনার সম্মুখীন হওয়া যেকোনো অস্বাভাবিক আচরণের সমাধান করতে নীচের নির্দেশিকা অনুসরণ করুন। এই নোটগুলি সিকিউরিটি রুলস ইউনিট টেস্টিং লাইব্রেরিকে মাথায় রেখে লেখা হয়েছে, তবে সাধারণ পদ্ধতিগুলি যেকোনো ফায়ারবেস SDK-এর ক্ষেত্রে প্রযোজ্য।

Test behavior is inconsistent

If your tests are occasionally passing and failing, even without any changes to the tests themselves, you might need to verify that they're properly sequenced. Most interactions with the emulator are asynchronous, so double-check that all the async code is properly sequenced. You can fix the sequencing by either chaining promises, or using await notation liberally.

বিশেষ করে, নিম্নলিখিত অ্যাসিঙ্ক অপারেশনগুলো পর্যালোচনা করুন:

  • নিরাপত্তা নিয়মাবলী নির্ধারণ করা, যেমন initializeTestEnvironment ব্যবহার করে।
  • ডেটা পড়া এবং লেখা, যেমন, db.collection("users").doc("alice").get()
  • অপারেশনাল অ্যাসারশন, যার মধ্যে assertSucceeds এবং assertFails অন্তর্ভুক্ত।

এমুলেটরটি প্রথমবার লোড করলেই কেবল টেস্টগুলো পাস হয়।

The emulator is stateful. It stores all the data written to it in memory, so any data is lost whenever the emulator shuts down. If you're running multiple tests against the same project id, each test can produce data that might influence subsequent tests. You can use any of the following methods to bypass this behavior:

  • Use unique project IDs for each test. Note that if you choose to do this you will need to call initializeTestEnvironment as part of each test; rules are only automatically loaded for the default project ID.
  • আপনার পরীক্ষাগুলোকে এমনভাবে পুনর্গঠন করুন যাতে সেগুলো পূর্বে লেখা ডেটার সাথে হস্তক্ষেপ না করে (উদাহরণস্বরূপ, প্রতিটি পরীক্ষার জন্য একটি ভিন্ন ডেটা সংগ্রহ ব্যবহার করুন)।
  • Delete all the data written during a test.

Test setup is very complicated

When setting up your test, you may want to modify data in a way that your Cloud Firestore Security Rules don't actually allow. If your rules are making test setup complex, try using RulesTestEnvironment.withSecurityRulesDisabled in your setup steps, so reads and writes won't trigger PERMISSION_DENIED errors.

After that, your test can perform operations as an authenticated or unauthenticated user using RulesTestEnvironment.authenticatedContext and unauthenticatedContext respectively. This allows you to validate that your Cloud Firestore Security Rules allows / denies different cases correctly.