আপনার পার্স অ্যান্ড্রয়েড অ্যাপ Firebase-এ স্থানান্তর করুন

আপনি যদি একজন পার্স ব্যবহারকারী হন একটি পরিষেবা সমাধান হিসাবে একটি বিকল্প ব্যাকএন্ড খুঁজছেন, Firebase হতে পারে আপনার Android অ্যাপের জন্য আদর্শ পছন্দ।

এই নির্দেশিকাটি বর্ণনা করে যে কীভাবে আপনার অ্যাপে নির্দিষ্ট পরিষেবাগুলিকে একীভূত করতে হয়। মৌলিক ফায়ারবেস সেটআপ নির্দেশাবলীর জন্য, Android সেটআপ নির্দেশিকা দেখুন।

গুগল বিশ্লেষক

গুগল অ্যানালিটিক্স হল একটি বিনামূল্যের অ্যাপ পরিমাপ সমাধান যা অ্যাপ ব্যবহার এবং ব্যবহারকারীর ব্যস্ততার অন্তর্দৃষ্টি প্রদান করে। Analytics Firebase বৈশিষ্ট্য জুড়ে একত্রিত করে এবং আপনাকে 500টি পর্যন্ত স্বতন্ত্র ইভেন্টের জন্য সীমাহীন প্রতিবেদন প্রদান করে যা আপনি Firebase SDK ব্যবহার করে সংজ্ঞায়িত করতে পারেন।

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

প্রস্তাবিত মাইগ্রেশন কৌশল

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

কাস্টম ইভেন্ট এবং ব্যবহারকারীর বৈশিষ্ট্যগুলির জন্য, আপনি ইভেন্ট এবং বৈশিষ্ট্যগুলি লগ করার জন্য পার্স অ্যানালিটিক্স এবং Google অ্যানালিটিক্স উভয় ব্যবহার করে একটি ডবল রাইটিং কৌশল নিযুক্ত করতে পারেন, যা আপনাকে ধীরে ধীরে নতুন সমাধান রোল আউট করতে দেয়৷

কোড তুলনা

বিশ্লেষণ পার্স

// Start collecting data
ParseAnalytics.trackAppOpenedInBackground(getIntent());

Map<String, String> dimensions = new HashMap<String, String>();
// Define ranges to bucket data points into meaningful segments
dimensions.put("priceRange", "1000-1500");
// Did the user filter the query?
dimensions.put("source", "craigslist");
// Do searches happen more often on weekdays or weekends?
dimensions.put("dayType", "weekday");

// Send the dimensions to Parse along with the 'search' event
ParseAnalytics.trackEvent("search", dimensions);

গুগল বিশ্লেষক

// Obtain the FirebaseAnalytics instance and start collecting data
mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);

Bundle params = new Bundle();
// Define ranges to bucket data points into meaningful segments
params.putString("priceRange", "1000-1500");
// Did the user filter the query?
params.putString("source", "craigslist");
// Do searches happen more often on weekdays or weekends?
params.putString("dayType", "weekday");

// Send the event
mFirebaseAnalytics.logEvent("search", params);

ফায়ারবেস রিয়েলটাইম ডাটাবেস

ফায়ারবেস রিয়েলটাইম ডেটাবেস হল একটি NoSQL ক্লাউড-হোস্টেড ডাটাবেস। ডেটা JSON হিসাবে সংরক্ষণ করা হয় এবং প্রতিটি সংযুক্ত ক্লায়েন্টের সাথে রিয়েল টাইমে সিঙ্ক্রোনাইজ করা হয়।

আরও জানতে ফায়ারবেস রিয়েলটাইম ডেটাবেস ডক্স দেখুন।

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

বস্তু

পার্সে আপনি একটি ParseObject বা এটির একটি সাবক্লাস সঞ্চয় করেন, যাতে JSON-সামঞ্জস্যপূর্ণ ডেটার কী-মানের জোড়া রয়েছে। ডেটা স্কিমলেস, যার মানে প্রতিটি ParseObject এ কোন কী বিদ্যমান তা নির্দিষ্ট করার প্রয়োজন নেই।

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

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

পার্স
@ParseClassName("GameScore")
public class GameScore {
        public GameScore() {}
        public GameScore(Long score, String playerName, Boolean cheatMode) {
            setScore(score);
            setPlayerName(playerName);
            setCheatMode(cheatMode);
        }

        public void setScore(Long score) {
            set("score", score);
        }

        public Long getScore() {
            return getLong("score");
        }

        public void setPlayerName(String playerName) {
            set("playerName", playerName);
        }

        public String getPlayerName() {
            return getString("playerName");
        }

        public void setCheatMode(Boolean cheatMode) {
            return set("cheatMode", cheatMode);
        }

        public Boolean getCheatMode() {
            return getBoolean("cheatMode");
        }
}

// Must call Parse.registerSubclass(GameScore.class) in Application.onCreate
GameScore gameScore = new GameScore(1337, "Sean Plott", false);
gameScore.saveInBackground();
ফায়ারবেস
// Assuming we defined the GameScore class as:
public class GameScore {
        private Long score;
        private String playerName;
        private Boolean cheatMode;

        public GameScore() {}
        public GameScore(Long score, String playerName, Boolean cheatMode) {
            this.score = score;
            this.playerName = playerName;
            this.cheatMode = cheatMode;
        }

        public Long getScore() {
            return score;
        }

        public String getPlayerName() {
            return playerName;
        }

        public Boolean getCheatMode() {
            return cheatMode;
        }
}

// We would save it to our list of high scores as follows:
DatabaseReference mFirebaseRef = FirebaseDatabase.getInstance().getReference();
GameScore score = new GameScore(1337, "Sean Plott", false);
mFirebaseRef.child("scores").push().setValue(score);
আরও বিশদ বিবরণের জন্য, অ্যান্ড্রয়েড গাইডে ডেটা পড়ুন এবং লিখুন দেখুন।

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

একটি ParseObject অন্য একটি ParseObject সাথে সম্পর্ক রাখতে পারে: যেকোন অবজেক্ট অন্য অবজেক্টকে মান হিসাবে ব্যবহার করতে পারে।

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

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

পার্স
// Create the author
ParseObject myAuthor = new ParseObject("Author");
myAuthor.put("name", "Grace Hopper");
myAuthor.put("birthDate", "December 9, 1906");
myAuthor.put("nickname", "Amazing Grace");

// Create the post
ParseObject myPost = new ParseObject("Post");
myPost.put("title", "Announcing COBOL, a New Programming Language");

// Add a relation between the Post and the Author
myPost.put("parent", myAuthor);

// This will save both myAuthor and myPost
myPost.saveInBackground();
ফায়ারবেস
DatabaseReference firebaseRef = FirebaseDatabase.getInstance().getReference();
// Create the author
Map<String, String> myAuthor = new HashMap<String, String>();
myAuthor.put("name", "Grace Hopper");
myAuthor.put("birthDate", "December 9, 1906");
myAuthor.put("nickname", "Amazing Grace");

// Save the author
String myAuthorKey = "ghopper";
firebaseRef.child('authors').child(myAuthorKey).setValue(myAuthor);

// Create the post
Map<String, String> post = new HashMap<String, String>();
post.put("author", myAuthorKey);
post.put("title", "Announcing COBOL, a New Programming Language");
firebaseRef.child('posts').push().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"
    }
    ...
  }
}
আরও বিস্তারিত জানার জন্য, আপনার ডাটাবেসের গঠন নির্দেশিকা দেখুন।

ডেটা পড়া

পার্সে আপনি একটি নির্দিষ্ট পার্স অবজেক্টের আইডি ব্যবহার করে বা ParseQuery ব্যবহার করে অনুসন্ধান চালানোর মাধ্যমে ডেটা পড়েন।

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

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

পার্স
ParseQuery<ParseObject> query = ParseQuery.getQuery("GameScore");
query.whereEqualTo("playerName", "Dan Stemkoski");
query.findInBackground(new FindCallback<ParseObject>() {
    public void done(List<ParseObject> scoreList, ParseException e) {
        if (e == null) {
            for (ParseObject score: scoreList) {
                Log.d("score", "Retrieved: " + Long.toString(score.getLong("score")));
            }
        } else {
            Log.d("score", "Error: " + e.getMessage());
        }
    }
});
ফায়ারবেস
DatabaseReference mFirebaseRef = FirebaseDatabase.getInstance().getReference();
Query mQueryRef = mFirebaseRef.child("scores").orderByChild("playerName").equalTo("Dan Stemkoski");

// This type of listener is not one time, and you need to cancel it to stop
// receiving updates.
mQueryRef.addChildEventListener(new ChildEventListener() {
    @Override
    public void onChildAdded(DataSnapshot snapshot, String previousChild) {
        // This will fire for each matching child node.
        GameScore score = snapshot.getValue(GameScore.class);
        Log.d("score", "Retrieved: " + Long.toString(score.getScore());
    }
});
উপলভ্য ধরনের ইভেন্ট শ্রোতাদের সম্পর্কে আরও বিশদ বিবরণের জন্য এবং কীভাবে ডেটা অর্ডার এবং ফিল্টার করতে হয়, অ্যান্ড্রয়েডে ডেটা পড়ুন এবং লিখুন নির্দেশিকা দেখুন।

প্রস্তাবিত মাইগ্রেশন কৌশল

আপনার ডেটা পুনর্বিবেচনা করুন

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

  • কিভাবে আপনার পার্স অবজেক্ট ফায়ারবেস ডেটাতে ম্যাপ করা উচিত
  • আপনার যদি পিতামাতা-সন্তানের সম্পর্ক থাকে তবে কীভাবে আপনার ডেটা বিভিন্ন পাথ জুড়ে বিভক্ত করবেন যাতে এটি আলাদা কলে দক্ষতার সাথে ডাউনলোড করা যায়।

আপনার ডেটা স্থানান্তর করুন

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

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

এই পরিস্থিতিতে, আপনার কাছে অ্যাপটির দুটি সংস্করণ রয়েছে: পুরানো সংস্করণ যা পার্স ব্যবহার করে এবং একটি নতুন সংস্করণ যা ফায়ারবেস ব্যবহার করে৷ দুটি ডাটাবেসের মধ্যে সিঙ্কগুলি পার্স ক্লাউড কোড (ফায়ারবেস থেকে পার্স) দ্বারা পরিচালিত হয়, আপনার কোড ফায়ারবেসের পরিবর্তনগুলি শুনে এবং সেই পরিবর্তনগুলিকে পার্সের সাথে সিঙ্ক করে৷ আপনি নতুন সংস্করণ ব্যবহার শুরু করার আগে, আপনাকে অবশ্যই:

  • আপনার বিদ্যমান পার্স ডেটাকে নতুন Firebase কাঠামোতে রূপান্তর করুন এবং Firebase রিয়েলটাইম ডেটাবেসে লিখুন।
  • পার্স ক্লাউড কোড ফাংশনগুলি লিখুন যেগুলি পুরানো ক্লায়েন্টদের দ্বারা পার্স ডেটাতে করা Firebase রিয়েলটাইম ডেটাবেসে পরিবর্তনগুলি লিখতে Firebase REST API ব্যবহার করে৷
  • কোড লিখুন এবং স্থাপন করুন যা ফায়ারবেসে পরিবর্তনগুলি শোনে এবং সেগুলিকে পার্স ডাটাবেসে সিঙ্ক করে৷

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

ডাবল লিখুন

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

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

ফায়ারবেস প্রমাণীকরণ

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

আরও জানতে Firebase প্রমাণীকরণ ডক্স দেখুন।

পার্স প্রমাণের সাথে পার্থক্য

পার্স ParseUser নামে একটি বিশেষ ব্যবহারকারী শ্রেণী প্রদান করে যা ব্যবহারকারীর অ্যাকাউন্ট পরিচালনার জন্য প্রয়োজনীয় কার্যকারিতা স্বয়ংক্রিয়ভাবে পরিচালনা করে। ParseUser হল ParseObject এর একটি সাবক্লাস, যার অর্থ ব্যবহারকারীর ডেটা পার্স ডেটাতে উপলব্ধ এবং অন্যান্য ParseObject এর মতো অতিরিক্ত ক্ষেত্রগুলির সাথে প্রসারিত করা যেতে পারে।

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

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

পার্স
ParseUser user = new ParseUser();
user.setUsername("my name");
user.setPassword("my pass");
user.setEmail("email@example.com");

// other fields can be set just like with ParseObject
user.put("phone", "650-253-0000");

user.signUpInBackground(new SignUpCallback() {
    public void done(ParseException e) {
        if (e == null) {
            // Hooray! Let them use the app now.
        } else {
            // Sign up didn't succeed. Look at the ParseException
            // to figure out what went wrong
        }
    }
});
ফায়ারবেস
FirebaseAuth mAuth = FirebaseAuth.getInstance();

mAuth.createUserWithEmailAndPassword("email@example.com", "my pass")
    .continueWithTask(new Continuation<AuthResult, Task<Void>> {
        @Override
        public Task<Void> then(Task<AuthResult> task) {
            if (task.isSuccessful()) {
                FirebaseUser user = task.getResult().getUser();
                DatabaseReference firebaseRef = FirebaseDatabase.getInstance().getReference();
                return firebaseRef.child("users").child(user.getUid()).child("phone").setValue("650-253-0000");
            } else {
                // User creation didn't succeed. Look at the task exception
                // to figure out what went wrong
                Log.w(TAG, "signInWithEmail", task.getException());
            }
        }
    });

প্রস্তাবিত মাইগ্রেশন কৌশল

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

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

প্রথমে, পার্স কনসোল বা আপনার স্ব-হোস্ট করা ডাটাবেস থেকে আপনার ব্যবহারকারীর ডাটাবেস রপ্তানি করুন। উদাহরণস্বরূপ, পার্স কনসোল থেকে রপ্তানি করা একটি 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 দ্বারা প্রয়োজনীয় বিন্যাসে রূপান্তর করুন৷ আপনার ফায়ারবেস ব্যবহারকারীদের localId হিসাবে আপনার পার্স ব্যবহারকারীদের objectId ব্যবহার করুন। এছাড়াও, base64 পার্স থেকে bcryptPassword মান এনকোড করুন এবং 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
        }
      ]
    }
  ]
}

অবশেষে, হ্যাশ অ্যালগরিদম হিসাবে bcrypt নির্দিষ্ট করে Firebase CLI দিয়ে রূপান্তরিত ফাইলটি আমদানি করুন:

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

ব্যবহারকারীর ডেটা স্থানান্তর করুন

আপনি যদি আপনার ব্যবহারকারীদের জন্য অতিরিক্ত ডেটা সঞ্চয় করে থাকেন তবে ডেটা মাইগ্রেশন বিভাগে বর্ণিত কৌশলগুলি ব্যবহার করে আপনি এটিকে Firebase রিয়েলটাইম ডেটাবেসে স্থানান্তর করতে পারেন। আপনি যদি অ্যাকাউন্ট মাইগ্রেশন বিভাগে বর্ণিত ফ্লো ব্যবহার করে অ্যাকাউন্টগুলি স্থানান্তর করেন, আপনার ফায়ারবেস অ্যাকাউন্টগুলিতে আপনার পার্স অ্যাকাউন্টগুলির একই আইডি থাকে, যা আপনাকে ব্যবহারকারী আইডি দ্বারা চাবি করা যেকোনো সম্পর্ককে সহজেই স্থানান্তর এবং পুনরুত্পাদন করতে দেয়।

ফায়ারবেস ক্লাউড মেসেজিং

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

আরও জানতে Firebase ক্লাউড মেসেজিং ডক্স দেখুন।

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

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

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

প্রস্তাবিত মাইগ্রেশন কৌশল

ডিভাইস টোকেন স্থানান্তর করা

লেখার সময়, পার্স অ্যান্ড্রয়েড SDK এফসিএম রেজিস্ট্রেশন টোকেনগুলির একটি পুরানো সংস্করণ ব্যবহার করে, বিজ্ঞপ্তি কম্পোজারের দেওয়া বৈশিষ্ট্যগুলির সাথে সামঞ্জস্যপূর্ণ নয়৷

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

চ্যানেলগুলিকে FCM বিষয়গুলিতে স্থানান্তর করা হচ্ছে৷

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

<service android:name="com.parse.PushService" />
<receiver android:name="com.parse.ParsePushBroadcastReceiver"
  android:exported="false">
<intent-filter>
<action android:name="com.parse.push.intent.RECEIVE" />
<action android:name="com.parse.push.intent.DELETE" />
<action android:name="com.parse.push.intent.OPEN" />
</intent-filter>
</receiver>
<receiver android:name="com.parse.GcmBroadcastReceiver"
  android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />

<!--
IMPORTANT: Change "com.parse.starter" to match your app's package name.
-->
<category android:name="com.parse.starter" />
</intent-filter>
</receiver>

<!--
IMPORTANT: Change "YOUR_SENDER_ID" to your GCM Sender Id.
-->
<meta-data android:name="com.parse.push.gcm_sender_id"
  android:value="id:YOUR_SENDER_ID" />;

উদাহরণস্বরূপ, যদি আপনার ব্যবহারকারী "জায়েন্টস" বিষয়ে সদস্যতা নেন, তাহলে আপনি এরকম কিছু করবেন:

ParsePush.unsubscribeInBackground("Giants", new SaveCallback() {
    @Override
    public void done(ParseException e) {
        if (e == null) {
            FirebaseMessaging.getInstance().subscribeToTopic("Giants");
        } else {
            // Something went wrong unsubscribing
        }
    }
});

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

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

ফায়ারবেস রিমোট কনফিগারেশন

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

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

ফায়ারবেস রিমোট কনফিগ সম্পর্কে আরও জানতে, রিমোট কনফিগার ভূমিকা দেখুন।

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

পার্স কনফিগারেশনের মাধ্যমে আপনি পার্স কনফিগার ড্যাশবোর্ডে আপনার অ্যাপে কী/মান জোড়া যোগ করতে পারেন এবং তারপর ক্লায়েন্টে ParseConfig আনতে পারেন। প্রতিটি ParseConfig উদাহরণ যা আপনি পান তা সর্বদা অপরিবর্তনীয়। আপনি যখন নেটওয়ার্ক থেকে ভবিষ্যতে একটি নতুন ParseConfig পুনরুদ্ধার করবেন, এটি কোনো বিদ্যমান ParseConfig উদাহরণ পরিবর্তন করবে না, বরং একটি নতুন তৈরি করবে এবং getCurrentConfig() এর মাধ্যমে উপলব্ধ করবে।

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

প্রস্তাবিত মাইগ্রেশন কৌশল

আপনি Firebase কনসোলে আপনার পার্স কনফিগারেশনের কী/মান জোড়া কপি করে Firebase রিমোট কনফিগারেশনে যেতে পারেন এবং তারপরে Firebase রিমোট কনফিগারেশন ব্যবহার করে এমন অ্যাপের একটি নতুন সংস্করণ স্থাপন করে।

আপনি যদি পার্স কনফিগ এবং ফায়ারবেস রিমোট কনফিগ উভয়ের সাথে পরীক্ষা করতে চান তবে আপনি অ্যাপের একটি নতুন সংস্করণ স্থাপন করতে পারেন যা উভয় SDK ব্যবহার করে যতক্ষণ না পর্যাপ্ত ব্যবহারকারীরা শুধুমাত্র পার্স সংস্করণ থেকে স্থানান্তরিত হয়।

কোড তুলনা

পার্স

ParseConfig.getInBackground(new ConfigCallback() {
    @Override
    public void done(ParseConfig config, ParseException e) {
        if (e == null) {
            Log.d("TAG", "Yay! Config was fetched from the server.");
        } else {
            Log.e("TAG", "Failed to fetch. Using Cached Config.");
            config = ParseConfig.getCurrentConfig();
        }

        // Get the message from config or fallback to default value
        String welcomeMessage = config.getString("welcomeMessage", "Welcome!");
    }
});

ফায়ারবেস

mFirebaseRemoteConfig = FirebaseRemoteConfig.getInstance();
// Set defaults from an XML resource file stored in res/xml
mFirebaseRemoteConfig.setDefaults(R.xml.remote_config_defaults);

mFirebaseRemoteConfig.fetch()
    .addOnSuccessListener(new OnSuccessListener<Void>() {
        @Override
        public void onSuccess(Void aVoid) {
            Log.d("TAG", "Yay! Config was fetched from the server.");
            // Once the config is successfully fetched it must be activated before newly fetched
            // values are returned.
            mFirebaseRemoteConfig.activateFetched();
        }
    })
    .addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception exception) {
            Log.e("TAG", "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.
String welcomeMessage = mFirebaseRemoteConfig.getString("welcomeMessage");