আপনার Parse iOS অ্যাপ Firebase-এ মাইগ্রেট করুন

আপনি যদি Parse ব্যবহারকারী হন এবং বিকল্প Backend as a Service সমাধান খুঁজছেন, তাহলে Firebase আপনার iOS অ্যাপের জন্য আদর্শ পছন্দ হতে পারে।

এই নির্দেশিকা আপনার অ্যাপে নির্দিষ্ট পরিষেবা কীভাবে ইন্টিগ্রেট করতে হয় তা বর্ণনা করে। Firebase সেট-আপের প্রাথমিক নির্দেশাবলীর জন্য, iOS+ সেট-আপ নির্দেশিকা দেখুন।

Google Analytics

Google Analytics হল একটি ফ্রি অ্যাপ পরিমাপ সংক্রান্ত সমাধান যা অ্যাপ ব্যবহার এবং ব্যবহারকারীর এনগেজমেন্ট সম্পর্কে ইনসাইট প্রদান করে। Analytics Firebase-এর বিভিন্ন ফিচারের সাথে ইন্টিগ্রেট করে এবং Firebase SDK ব্যবহার করে আপনি যে ৫০০টি আলাদা আলাদা ইভেন্টকে সংজ্ঞায়িত করতে পারেন, সেগুলির জন্য আপনাকে আনলিমিটেড রিপোর্টিং প্রদান করে।

আরও জানতে Google Analytics ডকুমেন্ট দেখুন।

মাইগ্রেশন সংক্রান্ত সাজেস্ট করা স্ট্র্যাটেজি

বিভিন্ন অ্যানালিটিক্স পরিষেবা প্রদানকারী ব্যবহার করা একটি সাধারণ দৃশ্য যা সহজেই Google Analytics-এ প্রযোজ্য। ইভেন্ট ও ব্যবহারকারীর প্রপার্টি থেকে সুবিধা পেতে, আপনার অ্যাপে এটি যোগ করুন। Analytics প্রথমবার খোলা, অ্যাপ আপডেট, ডিভাইস মডেল, বয়স ইত্যাদি তথ্য অটোমেটিক সংগ্রহ করা হয়।

কাস্টম ইভেন্ট এবং ব্যবহারকারীর তথ্যের জন্য, আপনি ইভেন্ট এবং প্রপার্টি লগ করতে Parse Analytics এবং Google Analytics উভয়ই ব্যবহার করে একটি ডবল রাইট স্ট্র্যাটেজি ব্যবহার করতে পারেন, যা আপনাকে ধীরে ধীরে নতুন সমাধান রোল আউট করতে দেয়।

কোড তুলনা করা

Parse Analytics

// Start collecting data
[PFAnalytics trackAppOpenedWithLaunchOptions:launchOptions];

NSDictionary *dimensions = @{
  // Define ranges to bucket data points into meaningful segments
  @"priceRange": @"1000-1500",
  // Did the user filter the query?
  @"source": @"craigslist",
  // Do searches happen more often on weekdays or weekends?
  @"dayType": @"weekday"
};
// Send the dimensions to Parse along with the 'search' event
[PFAnalytics trackEvent:@"search" dimensions:dimensions];

Google Analytics

// Obtain the AppMeasurement instance and start collecting data
[FIRApp configure];

// Send the event with your params
[FIRAnalytics logEventWithName:@"search" parameters:@{
  // Define ranges to bucket data points into meaningful segments
  @"priceRange": @"1000-1500",
  // Did the user filter the query?
  @"source": @"craigslist",
  // Do searches happen more often on weekdays or weekends?
  @"dayType": @"weekday"
}];

Firebase Realtime Database

Firebase Realtime Database হল NoSQL ক্লাউড-হোস্টেড ডেটাবেস। ডেটা JSON হিসেবে স্টোর করা হয় এবং কানেক্ট করা প্রতিটি ক্লায়েন্টের সাথে রিয়েল-টাইমে সিঙ্ক করা হয়।

আরও জানতে Firebase Realtime Database ডকুমেন্ট দেখুন।

পার্স ডেটার সাথে পার্থক্য

জিনিসপত্র

Parse-এ আপনি PFObject বা এর কোনও সাবক্লাস স্টোর করেন, যাতে JSON-এর সাথে মানানসই ডেটার কী-ভ্যালু পেয়ার থাকে। ডেটা স্কিমাহীন, যার অর্থ হল প্রতিটি PFObject-এ কোন কী আছে তা আপনাকে নির্দিষ্ট করতে হবে না।

সব Firebase Realtime Database ডেটা JSON অবজেক্ট হিসেবে স্টোর করা হয় এবং PFObject-এর সমতুল্য কিছু নেই; আপনি শুধু JSON ট্রি-তে এমন ধরনের ভ্যালু লেখেন যা উপলভ্য JSON ধরনের সাথে মেলে।

কোনও গেমের জন্য আপনি কীভাবে উচ্চ স্কোর সেভ করতে পারেন তার একটি উদাহরণ নিচে দেওয়া হল।

পার্স করা
PFObject *gameScore = [PFObject objectWithClassName:@"GameScore"];
gameScore[@"score"] = @1337;
gameScore[@"playerName"] = @"Sean Plott";
gameScore[@"cheatMode"] = @NO;
[gameScore saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
  if (succeeded) {
    // The object has been saved.
  } else {
    // There was a problem, check error.description
  }
}];
Firebase
// Create a reference to the database
FIRDatabaseReference *ref = [[FIRDatabase database] reference];
NSString *key = [[ref child:@"scores"] childByAutoId].key;
NSDictionary *score = @{@"score": @1337,
                        @"playerName": @"Sean Plott",
                        @"cheatMode": @NO};
[key setValue:score withCompletionBlock:^(NSError *error,  FIRDatabaseReference *ref) {
  if (error) {
    // The object has been saved.
  } else {
    // There was a problem, check error.description
  }
}];
আরও বিবরণের জন্য, Apple প্ল্যাটফর্মে ডেটা পড়া ও লেখা গাইড দেখুন।

ডেটার মধ্যে সম্পর্ক

একটি PFObject-এর সাথে অন্য একটি PFObject-এর সম্পর্ক থাকতে পারে: যেকোনও অবজেক্ট অন্য অবজেক্টকে ভ্যালু হিসেবে ব্যবহার করতে পারে।

Firebase Realtime Database-এ, ফ্ল্যাট ডেটা স্ট্রাকচার ব্যবহার করে সম্পর্ক আরও ভালোভাবে প্রকাশ করা হয় যা ডেটাকে আলাদা আলাদা পাথে ভাগ করে দেয়, যাতে সেগুলি আলাদা আলাদা কলের মাধ্যমে দক্ষতার সাথে ডাউনলোড করা যায়।

ব্লগিং অ্যাপে পোস্ট এবং তাদের লেখকদের মধ্যে সম্পর্ক কীভাবে গঠন করবেন তার একটি উদাহরণ নিচে দেওয়া হল।

পার্স করুন
// Create the author
PFObject *myAuthor = [PFObject objectWithClassName:@"Author"];
myAuthor[@"name"] = @"Grace Hopper";
myAuthor[@"birthDate"] = @"December 9, 1906";
myAuthor[@"nickname"] = @"Amazing Grace";

// Create the post
PFObject *myPost = [PFObject objectWithClassName:@"Post"];
myPost[@"title"] = @"Announcing COBOL, a New Programming Language";

// Add a relation between the Post and the Author
myPost[@"parent"] = myAuthor;

// This will save both myAuthor and myPost
[myPost saveInBackground];
Firebase
// Create a reference to the database
FIRDatabaseReference *ref = [[FIRDatabase database] reference];

// Create the author
NSString *myAuthorKey = @"ghopper";
NSDictionary *author = @{@"name": @"Grace Hopper",
                         @"birthDate": @"December 9, 1906",
                         @"nickname": @"Amazing Grace"};
// Save the author
[[ref child:myAuthorKey] setValue:author]

// Create and save the post
NSString *key = [[ref child:@"posts"] childByAutoId].key;
NSDictionary *post = @{@"author": myAuthorKey,
                       @"title": @"Announcing COBOL, a New Programming Language"};
[key setValue:post]

নিম্নলিখিত ডেটা লে-আউট হল ফলাফল।

{
  // Info about the authors
  "authors": {
    "ghopper": {
      "name": "Grace Hopper",
      "date_of_birth": "December 9, 1906",
      "nickname": "Amazing Grace"
    },
    ...
  },
  // Info about the posts: the "author" fields contains the key for the author
  "posts": {
    "-JRHTHaIs-jNPLXOQivY": {
      "author": "ghopper",
      "title": "Announcing COBOL, a New Programming Language"
    }
    ...
  }
}
আরও বিবরণের জন্য, এই আপনার ডেটাবেস স্ট্রাকচার করুন গাইড দেখুন।

রিডিং ডেটা

Parse-এ, আপনি নির্দিষ্ট Parse অবজেক্টের আইডি ব্যবহার করে ডেটা পড়েন অথবা PFQuery ব্যবহার করে কোয়েরি এক্সিকিউট করেন।

Firebase-এ, আপনি কোনও ডেটাবেস রেফারেন্সে অ্যাসিঙ্ক্রোনাস লিসনার অ্যাটাচ করে ডেটা রিট্রিভ করেন। ডেটার প্রাথমিক অবস্থার জন্য লিসনার একবার ট্রিগার হয় এবং ডেটা পরিবর্তিত হলে আবার ট্রিগার হয়। তাই ডেটা পরিবর্তিত হয়েছে কিনা তা নির্ধারণ করার জন্য আপনাকে কোনও কোড যোগ করতে হবে না।

"অবজেক্ট" বিভাগে দেখানো উদাহরণের ভিত্তিতে, আপনি কীভাবে কোনও নির্দিষ্ট প্লেয়ারের স্কোর রিট্রিভ করতে পারবেন, তার উদাহরণ নিচে দেওয়া হল।

পার্স করা
PFQuery *query = [PFQuery queryWithClassName:@"GameScore"];
[query whereKey:@"playerName" equalTo:@"Dan Stemkoski"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
  if (!error) {
    for (PFObject *score in objects) {
      NSString *gameScore = score[@"score"];
      NSLog(@"Retrieved: %@", gameScore);
    }
  } else {
    // Log details of the failure
    NSLog(@"Error: %@ %@", error, [error userInfo]);
  }
}];
Firebase
// Create a reference to the database
FIRDatabaseReference *ref = [[FIRDatabase database] reference];

// This type of listener is not one time, and you need to cancel it to stop
// receiving updates.
[[[[ref child:@"scores"] queryOrderedByChild:@"playerName"] queryEqualToValue:@"Dan Stemkoski"]
    observeEventType:FIRDataEventTypeChildAdded withBlock:^(FIRDataSnapshot *snapshot) {
  // This will fire for each matching child node.
  NSDictionary *score = snapshot.value;
  NSString gameScore = score[@"score"];
  NSLog(@"Retrieved: %@", gameScore);
}];
উপলভ্য ইভেন্ট লিসনারের ধরন এবং কীভাবে ডেটা অর্ডার ও ফিল্টার করতে হয় সেই সম্পর্কে আরও জানতে, Apple প্ল্যাটফর্মে ডেটা পড়া ও লেখা গাইড দেখুন।

মাইগ্রেশন সংক্রান্ত সাজেস্ট করা স্ট্র্যাটেজি

আপনার ডেটা নিয়ে নতুন করে ভাবুন

Firebase Realtime Database সবকটি কানেক্ট করা ক্লায়েন্ট জুড়ে মিলিসেকেন্ডে ডেটা সিঙ্ক করার জন্য অপ্টিমাইজ করা হয় এবং এর ফলে যে ডেটা স্ট্রাকচার তৈরি হয় তা Parse কোড ডেটা থেকে আলাদা হয়। এর অর্থ হল, আপনার মাইগ্রেশনের প্রথম ধাপ হল আপনার ডেটায় কী কী পরিবর্তন করতে হবে তা বিবেচনা করা, এর মধ্যে রয়েছে:

  • Firebase ডেটার সাথে আপনার Parse অবজেক্ট কীভাবে ম্যাপ করা উচিত
  • আপনার যদি পেরেন্ট-চাইল্ড সম্পর্ক থাকে, তাহলে কীভাবে আপনার ডেটা বিভিন্ন পাথে ভাগ করবেন যাতে সেটি আলাদা আলাদা কলে দক্ষতার সাথে ডাউনলোড করা যায়।

আপনার ডেটা মাইগ্রেট করা

Firebase-এ আপনার ডেটা কীভাবে স্ট্রাকচার করবেন তা ঠিক করার পরে, আপনাকে সেই সময়সীমা কীভাবে ম্যানেজ করবেন তা পরিকল্পনা করতে হবে যে সময়সীমার মধ্যে আপনার অ্যাপকে দুটি ডেটাবেসেই লিখতে হবে। আপনার বিকল্পগুলি হল:

ব্যাকগ্রাউন্ড সিঙ্ক

এই পরিস্থিতিতে, আপনার কাছে অ্যাপের দুটি ভার্সন আছে: পুরনো ভার্সন যা Parse ব্যবহার করে এবং নতুন ভার্সন যা Firebase ব্যবহার করে। দুটি ডেটাবেসের মধ্যে সিঙ্ক করার কাজটি Parse Cloud Code (Parse থেকে Firebase) দ্বারা ম্যানেজ করা হয়, আপনার কোড Firebase-এ হওয়া পরিবর্তনগুলি লক্ষ্য করে এবং সেই পরিবর্তনগুলি Parse-এর সাথে সিঙ্ক করে। নতুন ভার্সন ব্যবহার শুরু করার আগে, আপনাকে অবশ্যই:

  • আপনার আগে থেকে থাকা পার্স ডেটা নতুন Firebase স্ট্রাকচারে কনভার্ট করুন এবং এটি Firebase Realtime Database-এ লিখুন।
  • Parse Cloud কোড ফাংশন লিখুন যা Firebase REST API ব্যবহার করে Firebase Realtime Database পুরনো ক্লায়েন্টদের দ্বারা Parse ডেটাতে করা পরিবর্তনগুলি লেখে।
  • Firebase-এ হওয়া পরিবর্তনগুলি শোনে এবং সেগুলিকে Parse ডেটাবেসে সিঙ্ক করে এমন কোড লিখুন এবং ডিপ্লয় করুন।

এই পরিস্থিতিতে পুরনো ও নতুন কোড আলাদা করা নিশ্চিত করা হয় এবং ক্লায়েন্টকে সহজ রাখা হয়। এই পরিস্থিতির চ্যালেঞ্জ হল, প্রাথমিক এক্সপোর্ট করার সময় বড় ডেটাসেট ম্যানেজ করা এবং দ্বিমুখী সিঙ্ক যাতে অসীম রিকার্সন তৈরি না করে তা নিশ্চিত করা।

Double Write

এই পরিস্থিতিতে, আপনি অ্যাপের একটি নতুন ভার্সন লিখবেন যা Firebase এবং Parse, দুটিই ব্যবহার করে। এর জন্য Parse ডেটা থেকে পুরনো ক্লায়েন্টদের করা পরিবর্তনগুলি Firebase Realtime Database-এ সিঙ্ক করতে Parse Cloud Code ব্যবহার করুন। Parse-only ভার্সন থেকে যথেষ্ট সংখ্যক লোক মাইগ্রেট করে গেলে, আপনি ডবল রাইট ভার্সন থেকে Parse কোড সরিয়ে দিতে পারবেন।

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

Firebase Authentication

Firebase Authentication পাসওয়ার্ড ও Google, Facebook ও Twitter-এর মতো জনপ্রিয় ফেডারেটেড পরিচয় প্রদানকারী ব্যবহার করে ব্যবহারকারীদের প্রমাণীকরণ করতে পারে। এছাড়াও, এটি UI লাইব্রেরি প্রদান করে যা আপনাকে সমস্ত প্ল্যাটফর্ম জুড়ে আপনার অ্যাপের জন্য সম্পূর্ণ যাচাইকরণ অভিজ্ঞতা প্রয়োগ ও বজায় রাখার জন্য প্রয়োজনীয় উল্লেখযোগ্য ইনভেস্টমেন্ট থেকে বাঁচায়।

আরও জানতে Firebase Authentication ডকুমেন্ট দেখুন।

Parse Auth-এর সাথে পার্থক্য

Parse, PFUser নামে একটি বিশেষ ব্যবহারকারী ক্লাস প্রদান করে যা ব্যবহারকারীর অ্যাকাউন্ট ম্যানেজমেন্টের জন্য প্রয়োজনীয় কার্যকারিতা অটোমেটিক ম্যানেজ করে। PFUser হল PFObject-এর একটি সাবক্লাস, যার অর্থ হল ব্যবহারকারীর ডেটা Parse Data-তে উপলভ্য এবং অন্য যেকোনও PFObject-এর মতো অতিরিক্ত ফিল্ডের মাধ্যমে এটিকে এক্সটেন্ড করা যেতে পারে।

FIRUser-এর একটি নির্দিষ্ট সেট মৌলিক প্রপার্টি আছে—একটি অনন্য আইডি, একটি প্রাথমিক ইমেল আইডি, একটি নাম এবং একটি ফটো URL—একটি পৃথক প্রোজেক্টের ব্যবহারকারী ডেটাবেসে স্টোর করা; সেই প্রপার্টিগুলি ব্যবহারকারী আপডেট করতে পারেন। আপনি সরাসরি FIRUser অবজেক্টে অন্যান্য প্রপার্টি যোগ করতে পারবেন না; পরিবর্তে, আপনি অতিরিক্ত প্রপার্টি আপনার Firebase Realtime Database-এ স্টোর করতে পারবেন।

আপনি কীভাবে কোনও ব্যবহারকারীকে সাইন-আপ করতে এবং অতিরিক্ত ফোন নম্বর ফিল্ড যোগ করতে পারেন তার একটি উদাহরণ নিচে দেওয়া হল।

পার্স করা
PFUser *user = [PFUser user];
user.username = @"my name";
user.password = @"my pass";
user.email = @"email@example.com";

// other fields can be set just like with PFObject
user[@"phone"] = @"415-392-0202";

[user signUpInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
  if (!error) {
    // Hooray! Let them use the app now.
  } else {
    // Something went wrong
    NSString *errorString = [error userInfo][@"error"];
  }
}];
Firebase
[[FIRAuth auth] createUserWithEmail:@"email@example.com"
                           password:@"my pass"
                         completion:^(FIRUser *_Nullable user, NSError *_Nullable error) {
  if (!error) {
    FIRDatabaseReference *ref = [[FIRDatabase database] reference];
    [[[[ref child:@"users"] child:user.uid] child:@"phone"] setValue:@"415-392-0202"
  } else {
    // Something went wrong
    NSString *errorString = [error userInfo][@"error"];
  }
}];

মাইগ্রেশন সংক্রান্ত সাজেস্ট করা স্ট্র্যাটেজি

অ্যাকাউন্ট মাইগ্রেট করুন

Parse থেকে Firebase-এ ব্যবহারকারীর অ্যাকাউন্ট মাইগ্রেট করতে, আপনার ব্যবহারকারীর ডেটাবেস JSON বা CSV ফাইলে এক্সপোর্ট করুন, তারপর Firebase CLI-এর auth:import কমান্ড ব্যবহার করে আপনার Firebase প্রোজেক্টে ফাইলটি ইমপোর্ট করুন।

প্রথমে, Parse কনসোল বা আপনার সেল্ফ-হোস্টেড ডেটাবেস থেকে ব্যবহারকারীর ডেটাবেস এক্সপোর্ট করুন। যেমন, Parse কনসোল থেকে এক্সপোর্ট করা JSON ফাইলটি নিম্নলিখিত ফাইলের মতো দেখতে হতে পারে:

{ // Username/password user
  "bcryptPassword": "$2a$10$OBp2hxB7TaYZgKyTiY48luawlTuYAU6BqzxJfpHoJMdZmjaF4HFh6",
  "email": "user@example.com",
  "username": "testuser",
  "objectId": "abcde1234",
  ...
},
{ // Facebook user
  "authData": {
    "facebook": {
      "access_token": "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
      "expiration_date": "2017-01-02T03:04:05.006Z",
      "id": "1000000000"
    }
  },
  "username": "wXyZ987654321StUv",
  "objectId": "fghij5678",
  ...
}

তারপর, এক্সপোর্ট করা ফাইলটি Firebase CLI-এর জন্য প্রয়োজনীয় ফর্ম্যাটে রূপান্তর করুন। আপনার Parse ব্যবহারকারীর objectId, আপনার Firebase ব্যবহারকারীর localId হিসেবে ব্যবহার করুন। এছাড়াও, Parse থেকে পাওয়া bcryptPassword ভ্যালু base64 এনকোড করুন এবং passwordHash ফিল্ডে ব্যবহার করুন। যেমন:

{
  "users": [
    {
      "localId": "abcde1234",  // Parse objectId
      "email": "user@example.com",
      "displayName": "testuser",
      "passwordHash": "JDJhJDEwJE9CcDJoeEI3VGFZWmdLeVRpWTQ4bHVhd2xUdVlBVTZCcXp4SmZwSG9KTWRabWphRjRIRmg2",
    },
    {
      "localId": "fghij5678",  // Parse objectId
      "displayName": "wXyZ987654321StUv",
      "providerUserInfo": [
        {
          "providerId": "facebook.com",
          "rawId": "1000000000",  // Facebook ID
        }
      ]
    }
  ]
}

সবশেষে, Firebase CLI-এর মাধ্যমে ট্রান্সফর্ম করা ফাইলটি ইমপোর্ট করুন এবং হ্যাশ অ্যালগরিদম হিসেবে bcrypt নির্দিষ্ট করুন:

firebase auth:import account_file.json --hash-algo=BCRYPT

ব্যবহারকারীর ডেটা মাইগ্রেট করুন

আপনি যদি ব্যবহারকারীদের জন্য অতিরিক্ত ডেটা স্টোর করেন, তাহলে ডেটা মাইগ্রেশন বিভাগে বর্ণিত কৌশলগুলি ব্যবহার করে আপনি এটি Firebase Realtime Database-এ মাইগ্রেট করতে পারেন। অ্যাকাউন্ট মাইগ্রেশন বিভাগে বর্ণিত ফ্লো ব্যবহার করে অ্যাকাউন্ট মাইগ্রেট করলে, আপনার Firebase অ্যাকাউন্টের আইডি আপনার Parse অ্যাকাউন্টের আইডির মতো হবে, যা আপনাকে সহজেই মাইগ্রেট করতে এবং ব্যবহারকারীর আইডি দ্বারা কী করা যেকোনও সম্পর্ককে পুনঃপ্রযোজন করতে সাহায্য করবে।

Firebase Cloud Messaging

Firebase Cloud Messaging (FCM) হল একটি ক্রস-প্ল্যাটফর্ম মেসেজিং সমাধান যা আপনাকে কোনও খরচ ছাড়াই নির্ভরযোগ্যভাবে মেসেজ এবং বিজ্ঞপ্তি ডেলিভার করতে দেয়। বিজ্ঞপ্তি কম্পোজার হল একটি ফ্রি পরিষেবা যা Firebase Cloud Messaging-এ তৈরি করা হয়েছে। এটি মোবাইল অ্যাপ ডেভেলপারদের জন্য টার্গেট করা ব্যবহারকারীর বিজ্ঞপ্তি চালু করে।

আরও জানতে Firebase Cloud Messaging ডকুমেন্ট দেখুন।

Parse পুশ বিজ্ঞপ্তির সাথে পার্থক্য

বিজ্ঞপ্তির জন্য রেজিস্টার করা ডিভাইসে ইনস্টল করা প্রতিটি Parse অ্যাপ্লিকেশনের সাথে একটি Installation অবজেক্ট থাকে, যেখানে আপনি বিজ্ঞপ্তি টার্গেট করার জন্য প্রয়োজনীয় সমস্ত ডেটা স্টোর করেন। Installation হল PFUser-এর একটি সাবক্লাস, যার অর্থ হল আপনি নিজের Installation ইনস্ট্যান্সে যেকোনও অতিরিক্ত ডেটা যোগ করতে পারবেন।

বিজ্ঞপ্তি কম্পোজার অ্যাপ, অ্যাপের ভার্সন ও ডিভাইসের ভাষার মতো তথ্যের ভিত্তিতে আগে থেকে নির্ধারিত ব্যবহারকারীর বিভাগ প্রদান করে। আপনি Google Analyticsটি ইভেন্ট ও প্রপার্টি ব্যবহার করে আরও জটিল ব্যবহারকারীর বিভাগ তৈরি করতে পারবেন যাতে অডিয়েন্স তৈরি করা যায়। আরও জানতে দর্শক সম্পর্কিত সহায়তা গাইড দেখুন। এইসব টার্গেটিং তথ্য Firebase Realtime Database-এ দেখা যায় না।

মাইগ্রেশন সংক্রান্ত সাজেস্ট করা স্ট্র্যাটেজি

ডিভাইস টোকেন মাইগ্রেট করা

বিজ্ঞপ্তির জন্য ইনস্টলেশন টার্গেট করতে Parse, APNs ডিভাইস টোকেন ব্যবহার করে, FCM APNs ডিভাইস টোকেনে ম্যাপ করা FCM রেজিস্ট্রেশন টোকেন ব্যবহার করে। আপনার Apple অ্যাপে শুধু FCM SDK যোগ করুন এবং এটি অটোমেটিক FCM টোকেন নিয়ে আসবে।

চ্যানেলকে FCM বিষয়ে মাইগ্রেট করা

আপনি বিজ্ঞপ্তি পাঠানোর জন্য Parse চ্যানেল ব্যবহার করলে, FCM বিষয়ে মাইগ্রেট করতে পারবেন, যা একই প্রকাশক-সাবস্ক্রাইবার মডেল প্রদান করে। Parse থেকে FCM-এ ট্রানজিশন ম্যানেজ করতে, আপনি অ্যাপের নতুন ভার্সন লিখতে পারেন যা Parse চ্যানেল থেকে আনসাবস্ক্রাইব করতে Parse SDK এবং সংশ্লিষ্ট FCM বিষয়ে সাবস্ক্রাইব করতে FCM SDK ব্যবহার করে।

যেমন, আপনার ব্যবহারকারী "Giants" বিষয়ে সাবস্ক্রাইব করলে, আপনি এই ধরনের কিছু করতে পারেন:

PFInstallation *currentInstallation = [PFInstallation currentInstallation];
[currentInstallation removeObject:@"Giants" forKey:@"channels"];
[currentInstallation saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
  if (succeeded) {
    [[FIRMessaging messaging] subscribeToTopic:@"/topics/Giants"];
  } else {
    // Something went wrong unsubscribing
  }
}];

এই স্ট্র্যাটেজি ব্যবহার করে, আপনি Parse চ্যানেল এবং সংশ্লিষ্ট FCM বিষয়ে মেসেজ পাঠাতে পারবেন, যা পুরনো ও নতুন ভার্সনের ব্যবহারকারীদের সাহায্য করবে। অ্যাপের শুধু-পার্স ভার্সন থেকে পর্যাপ্ত সংখ্যক ব্যবহারকারী মাইগ্রেট করে গেলে, আপনি সেই ভার্সন বন্ধ করে দিতে পারেন এবং শুধু FCM ব্যবহার করে পাঠানো শুরু করতে পারেন।

আরও জানতে FCM বিষয় সংক্রান্ত ডকুমেন্ট দেখুন।

Firebase Remote Config

Firebase Remote Config হল একটি ক্লাউড পরিষেবা যা ব্যবহারকারীদের জন্য কোনও অ্যাপ আপডেট ডাউনলোড করার প্রয়োজন ছাড়াই আপনাকে নিজের অ্যাপ কীভাবে কাজ করবে তা এবং এটির লেআউট পরিবর্তন করতে দেয়। 'রিমোট কনফিগ' ব্যবহার করার সময়, আপনি অ্যাপ-মধ্যস্থ ডিফল্ট ভ্যালু তৈরি করেন যা আপনার অ্যাপের আচরণ ও চেহারা নিয়ন্ত্রণ করে। তারপর, আপনি পরে Firebase কনসোল ব্যবহার করে সব অ্যাপ ব্যবহারকারী বা আপনার ব্যবহারকারীর সেগমেন্টের জন্য অ্যাপ-মধ্যস্থ ডিফল্ট ভ্যালু ওভাররাইড করতে পারবেন।

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

Firebase Remote Config সম্পর্কে আরও জানতে, Remote Config ভূমিকা দেখুন।

Parse কনফিগারেশনের সাথে পার্থক্য

Parse কনফিগারেশনের মাধ্যমে আপনি Parse কনফিগারেশন ড্যাশবোর্ডে আপনার অ্যাপে কী/ভ্যালু পেয়ার যোগ করতে পারবেন এবং তারপর ক্লায়েন্টে PFConfig ফেচ করতে পারবেন। আপনি যে PFConfig ইনস্ট্যান্স পান, সেটি সবসময় অপরিবর্তনীয় হয়। ভবিষ্যতে নেটওয়ার্ক থেকে নতুন PFConfig নিয়ে এলে, এটি আগে থেকে থাকা কোনও PFConfig ইনস্ট্যান্সকে পরিবর্তন করবে না, তবে এর পরিবর্তে একটি নতুন ইনস্ট্যান্স তৈরি করবে এবং currentConfig-এর মাধ্যমে এটি উপলভ্য করবে।

Firebase Remote Config-এর সাহায্যে আপনি কী/ভ্যালু পেয়ারের জন্য ইন-অ্যাপ ডিফল্ট তৈরি করেন যা আপনি Firebase কনসোল থেকে ওভাররাইড করতে পারেন এবং আপনার অ্যাপের ব্যবহারকারীর অভিজ্ঞতাকে আপনার ব্যবহারকারীর বেসের বিভিন্ন বিভাগে আলাদা আলাদা করে প্রদান করতে, আপনি নিয়ম ও শর্তাবলী ব্যবহার করতে পারেন। Firebase Remote Config একটি সিঙ্গলটন ক্লাস প্রয়োগ করে যা আপনার অ্যাপে 'কী'/ভ্যালু পেয়ার উপলভ্য করে। প্রাথমিকভাবে সিঙ্গলটন আপনার অ্যাপ-মধ্যস্থ ডিফাইন করা ডিফল্ট ভ্যালু ফিরিয়ে দেয়। আপনার অ্যাপের জন্য সুবিধাজনক যেকোনও মুহূর্তে আপনি সার্ভার থেকে নতুন সেট অফ ভ্যালু ফেচ করতে পারবেন; নতুন সেট সফলভাবে ফেচ করার পরে, অ্যাপে নতুন ভ্যালু উপলভ্য করার জন্য আপনি কখন এটি অ্যাক্টিভেট করবেন তা বেছে নিতে পারবেন।

মাইগ্রেশন সংক্রান্ত সাজেস্ট করা স্ট্র্যাটেজি

Firebase কনসোলে আপনার Parse কনফিগারেশনের কী/ভ্যালু পেয়ার কপি করে এবং তারপর Firebase Remote Config ব্যবহার করে এমন অ্যাপের নতুন ভার্সন ডেপ্লয় করে আপনি Firebase Remote Config-এ যেতে পারবেন।

আপনি যদি Parse Config ও Firebase Remote Config, দুটিই নিয়ে পরীক্ষা করতে চান, তাহলে অ্যাপের একটি নতুন ভার্সন ডেপ্লয় করতে পারেন যেটি পর্যাপ্ত সংখ্যক ব্যবহারকারী শুধুমাত্র Parse ভার্সন থেকে মাইগ্রেট না করা পর্যন্ত দুটি SDK ব্যবহার করে।

কোডের তুলনা

পার্স করুন

[PFConfig getConfigInBackgroundWithBlock:^(PFConfig *config, NSError *error) {
  if (!error) {
    NSLog(@"Yay! Config was fetched from the server.");
  } else {
    NSLog(@"Failed to fetch. Using Cached Config.");
    config = [PFConfig currentConfig];
  }

  NSString *welcomeMessage = config[@"welcomeMessage"];
  if (!welcomeMessage) {
    NSLog(@"Falling back to default message.");
    welcomeMessage = @"Welcome!";
  }
}];

Firebase

FIRRemoteConfig remoteConfig = [FIRRemoteConfig remoteConfig];
// Set defaults from a plist file
[remoteConfig setDefaultsFromPlistFileName:@"RemoteConfigDefaults"];

[remoteConfig fetchWithCompletionHandler:^(FIRRemoteConfigFetchStatus status, NSError *error) {
  if (status == FIRRemoteConfigFetchStatusSuccess) {
    NSLog(@"Yay! Config was fetched from the server.");
    // Once the config is successfully fetched it must be activated before newly fetched
    // values are returned.
    [self.remoteConfig activateFetched];
  } else {
    NSLog(@"Failed to fetch. Using last fetched or default.");
  }
}];

// ...

// When this is called, the value of the latest fetched and activated config is returned;
// if there's none, the default value is returned.
NSString welcomeMessage = remoteConfig[@"welcomeMessage"].stringValue;