शुरू करने से पहले
Realtime Database का इस्तेमाल करने से पहले, आपको ये काम करने होंगे:
अपने Unity प्रोजेक्ट को रजिस्टर करें और उसे Firebase का इस्तेमाल करने के लिए कॉन्फ़िगर करें.
अगर आपका Unity प्रोजेक्ट पहले से ही Firebase का इस्तेमाल करता है, तो इसका मतलब है कि वह Firebase के लिए पहले से ही रजिस्टर और कॉन्फ़िगर किया गया है.
अगर आपके पास Unity प्रोजेक्ट नहीं है, तो सैंपल के तौर पर मिला ऐप्लिकेशन डाउनलोड किया जा सकता है.
अपने Unity प्रोजेक्ट में, Firebase Unity SDK (खास तौर पर,
FirebaseDatabase.unitypackage) जोड़ें.
ध्यान दें कि अपने Unity प्रोजेक्ट में Firebase जोड़ने के लिए, आपको Firebase कंसोल और अपने खुले हुए Unity प्रोजेक्ट, दोनों में टास्क करने होंगे. उदाहरण के लिए, कंसोल से Firebase की कॉन्फ़िगरेशन फ़ाइलें डाउनलोड करें और फिर उन्हें अपने Unity प्रोजेक्ट में ले जाएं.
डेटा सेव करना
Firebase Realtime Database में डेटा लिखने के पांच तरीके हैं:
| तरीका | सामान्य तौर पर क्वेरी की सूची का इस्तेमाल इस तरह किया जाता है |
|---|---|
SetValueAsync() |
तय किए गए पाथ में डेटा लिखें या बदलें, जैसे कि
users/<user-id>/<username>. |
SetRawJsonValueAsync() |
रॉ JSON का इस्तेमाल करके डेटा लिखें या बदलें, जैसे कि
users/<user-id>/<username>. |
Push() |
डेटा की सूची में जोड़ें. जब भी Push() को कॉल किया जाता है, तब Firebase एक यूनीक कुंजी जनरेट करता है. इसका इस्तेमाल यूनीक आइडेंटिफ़ायर के तौर पर भी किया जा सकता है, जैसे कि user-scores/<user-id>/<unique-score-id>. |
UpdateChildrenAsync() |
तय किए गए पाथ के लिए कुछ कुंजियों को अपडेट करना, लेकिन पूरे डेटा को न बदलना. |
RunTransaction() |
ऐसे जटिल डेटा को अपडेट करना जो एक साथ होने वाले अपडेट की वजह से खराब हो सकता है. |
DatabaseReference पाना
डेटाबेस में डेटा लिखने के लिए, आपको DatabaseReference के इंस्टेंस की ज़रूरत होगी:
using Firebase; using Firebase.Database; public class MyScript: MonoBehaviour { void Start() { // Get the root reference location of the database. DatabaseReference reference = FirebaseDatabase.DefaultInstance.RootReference; } }
किसी रेफ़रंस में डेटा लिखना, अपडेट करना या मिटाना
डेटा में बदलाव करने की बुनियादी कार्रवाइयां
डेटा को सेव करने के लिए, SetValueAsync() का इस्तेमाल किया जा सकता है. इससे डेटा, दिए गए रेफ़रंस में सेव हो जाता है और उस पाथ पर मौजूद मौजूदा डेटा को बदल देता है. इस तरीके का इस्तेमाल करके, उपलब्ध JSON टाइप से जुड़े टाइप पास किए जा सकते हैं. जैसे:
stringlongdoubleboolDictionary<string, Object>List<Object>
अगर टाइप किए गए C# ऑब्जेक्ट का इस्तेमाल किया जाता है, तो ऑब्जेक्ट को रॉ JSON में बदलने और SetRawJsonValueAsync() को कॉल करने के लिए, पहले से मौजूद JsonUtility.ToJson() का इस्तेमाल किया जा सकता है.
उदाहरण के लिए, आपके पास कोई User क्लास हो सकती है, जो इस तरह दिखती है:
public class User { public string username; public string email; public User() { } public User(string username, string email) { this.username = username; this.email = email; } }
SetRawJsonValueAsync() का इस्तेमाल करके, किसी उपयोगकर्ता को इस तरह जोड़ा जा सकता है:
private void writeNewUser(string userId, string name, string email) { User user = new User(name, email); string json = JsonUtility.ToJson(user); mDatabaseRef.Child("users").Child(userId).SetRawJsonValueAsync(json); }
इस तरह से SetValueAsync() या SetRawJsonValueAsync() का इस्तेमाल करने पर, तय की गई जगह पर मौजूद डेटा को ओवरराइट कर दिया जाता है. इसमें चाइल्ड नोड भी शामिल हैं. हालांकि, पूरे ऑब्जेक्ट को फिर से लिखे बिना भी चाइल्ड ऑब्जेक्ट को अपडेट किया जा सकता है. अगर आपको उपयोगकर्ताओं को अपनी प्रोफ़ाइल अपडेट करने की अनुमति देनी है, तो उपयोगकर्ता नाम को इस तरह अपडेट किया जा सकता है:
mDatabaseRef.Child("users").Child(userId).Child("username").SetValueAsync(name);
डेटा की सूची में जोड़ना
एक से ज़्यादा उपयोगकर्ताओं वाले ऐप्लिकेशन में, किसी सूची में डेटा जोड़ने के लिए Push() तरीके का इस्तेमाल करें.
Push() मेथड, Firebase के किसी रेफ़रंस में नया चाइल्ड जोड़ने पर हर बार एक यूनीक कुंजी जनरेट करता है. सूची में मौजूद हर नए एलिमेंट के लिए, अपने-आप जनरेट होने वाली इन कुंजियों का इस्तेमाल करके, कई क्लाइंट एक ही समय पर एक ही जगह पर चाइल्ड एलिमेंट जोड़ सकते हैं. इससे, डेटा लिखने में कोई समस्या नहीं होती. Push() से जनरेट की गई यूनीक कुंजी, टाइमस्टैंप पर आधारित होती है. इसलिए, सूची के आइटम अपने-आप समय के हिसाब से क्रम में लग जाते हैं.
Push() तरीके से मिले नए डेटा के रेफ़रंस का इस्तेमाल करके, चाइल्ड की अपने-आप जनरेट हुई कुंजी की वैल्यू पाई जा सकती है या चाइल्ड के लिए डेटा सेट किया जा सकता है. Push() रेफ़रंस पर Key को कॉल करने से, अपने-आप जनरेट हुई कुंजी की वैल्यू मिलती है.
चुनिंदा फ़ील्ड अपडेट करना
किसी नोड के कुछ चाइल्ड नोड में एक साथ डेटा लिखने के लिए, UpdateChildrenAsync() तरीके का इस्तेमाल करें. इससे अन्य चाइल्ड नोड का डेटा ओवरराइट नहीं होता.
UpdateChildrenAsync() को कॉल करते समय, कुंजी के लिए पाथ तय करके, निचले लेवल की चाइल्ड वैल्यू को अपडेट किया जा सकता है. अगर डेटा को बेहतर तरीके से स्केल करने के लिए कई जगहों पर सेव किया गया है, तो डेटा फ़ैन-आउट का इस्तेमाल करके, उस डेटा के सभी इंस्टेंस अपडेट किए जा सकते हैं. उदाहरण के लिए, किसी गेम में इस तरह की LeaderboardEntry क्लास हो सकती है:
public class LeaderboardEntry { public string uid; public int score = 0; public LeaderboardEntry() { } public LeaderboardEntry(string uid, int score) { this.uid = uid; this.score = score; } public Dictionary<string, Object> ToDictionary() { Dictionary<string, Object> result = new Dictionary<string, Object>(); result["uid"] = uid; result["score"] = score; return result; } }
लीडरबोर्ड एंट्री बनाने और उसे हाल ही के स्कोर फ़ीड और उपयोगकर्ता की स्कोर सूची में अपडेट करने के लिए, गेम इस तरह के कोड का इस्तेमाल करता है:
private void WriteNewScore(string userId, int score) { // Create new entry at /user-scores/$userid/$scoreid and at // /leaderboard/$scoreid simultaneously string key = mDatabase.Child("scores").Push().Key; LeaderBoardEntry entry = new LeaderBoardEntry(userId, score); Dictionary<string, Object> entryValues = entry.ToDictionary(); Dictionary<string, Object> childUpdates = new Dictionary<string, Object>(); childUpdates["/scores/" + key] = entryValues; childUpdates["/user-scores/" + userId + "/" + key] = entryValues; mDatabase.UpdateChildrenAsync(childUpdates); }
इस उदाहरण में, Push() का इस्तेमाल करके, नोड में एक एंट्री बनाई गई है. इसमें /scores/$key पर मौजूद सभी उपयोगकर्ताओं की एंट्री शामिल हैं. साथ ही, Key का इस्तेमाल करके, कुंजी को वापस लाया गया है. इसके बाद, इस कुंजी का इस्तेमाल करके, /user-scores/$userid/$key पर उपयोगकर्ता के स्कोर में दूसरी एंट्री बनाई जा सकती है.
इन पाथ का इस्तेमाल करके, JSON ट्री में मौजूद कई जगहों को एक साथ अपडेट किया जा सकता है. इसके लिए, UpdateChildrenAsync() को एक बार कॉल करना होगा. इस उदाहरण में, दोनों जगहों पर नई एंट्री बनाने का तरीका बताया गया है. इस तरह से एक साथ किए गए अपडेट, ऐटॉमिक होते हैं: या तो सभी अपडेट सफल होते हैं या सभी अपडेट फ़ेल हो जाते हैं.
डाटा हटाएं
डेटा मिटाने का सबसे आसान तरीका है कि उस डेटा की जगह के रेफ़रंस पर RemoveValue() को कॉल करें.
null को किसी अन्य राइट ऑपरेशन, जैसे कि SetValueAsync() या UpdateChildrenAsync() की वैल्यू के तौर पर तय करके भी मिटाया जा सकता है. एक ही एपीआई कॉल में कई चाइल्ड ऑब्जेक्ट मिटाने के लिए, UpdateChildrenAsync() के साथ इस तकनीक का इस्तेमाल किया जा सकता है.
जानें कि आपका डेटा कब कमिट किया जाता है.
यह जानने के लिए कि आपका डेटा Firebase Realtime Database सर्वर पर कब कमिट किया गया है, आपके पास एक कंटिन्यूएशन जोड़ने का विकल्प है. SetValueAsync() और UpdateChildrenAsync(), दोनों ही Task दिखाते हैं. इससे आपको पता चलता है कि कार्रवाई कब पूरी हुई. अगर किसी वजह से कॉल नहीं हो पाता है, तो Tasks IsFaulted की वैल्यू true होगी. साथ ही, Exception प्रॉपर्टी से पता चलेगा कि कॉल क्यों नहीं हो पाया.
डेटा को लेन-देन के तौर पर सेव करना
जब ऐसे डेटा के साथ काम किया जा रहा हो जो एक साथ किए गए बदलावों की वजह से खराब हो सकता है, जैसे कि बढ़ने वाले काउंटर, तो ट्रांज़ैक्शन ऑपरेशन का इस्तेमाल किया जा सकता है.
इस कार्रवाई को Func दें. यह अपडेट Func, डेटा की मौजूदा स्थिति को आर्ग्युमेंट के तौर पर लेता है. साथ ही, वह नई स्थिति दिखाता है जिसे आपको लिखना है. अगर आपकी नई वैल्यू को सेव किए जाने से पहले, कोई दूसरा क्लाइंट उस जगह पर डेटा सेव करता है, तो अपडेट फ़ंक्शन को नई मौजूदा वैल्यू के साथ फिर से कॉल किया जाता है. साथ ही, डेटा को सेव करने की कोशिश फिर से की जाती है.
उदाहरण के लिए, किसी गेम में उपयोगकर्ताओं को पांच सबसे ज़्यादा स्कोर के साथ लीडरबोर्ड अपडेट करने की अनुमति दी जा सकती है:
private void AddScoreToLeaders(string email, long score, DatabaseReference leaderBoardRef) { leaderBoardRef.RunTransaction(mutableData => { List<object> leaders = mutableData.Value as List<object> if (leaders == null) { leaders = new List<object>(); } else if (mutableData.ChildrenCount >= MaxScores) { long minScore = long.MaxValue; object minVal = null; foreach (var child in leaders) { if (!(child is Dictionary<string, object>)) continue; long childScore = (long) ((Dictionary<string, object>)child)["score"]; if (childScore < minScore) { minScore = childScore; minVal = child; } } if (minScore > score) { // The new score is lower than the existing 5 scores, abort. return TransactionResult.Abort(); } // Remove the lowest score. leaders.Remove(minVal); } // Add the new high score. Dictionary<string, object> newScoreMap = new Dictionary<string, object>(); newScoreMap["score"] = score; newScoreMap["email"] = email; leaders.Add(newScoreMap); mutableData.Value = leaders; return TransactionResult.Success(mutableData); }); }
लेन-देन का इस्तेमाल करने से, लीडरबोर्ड में गलत जानकारी दिखने से बचा जा सकता है. ऐसा तब होता है, जब कई उपयोगकर्ता एक ही समय पर स्कोर रिकॉर्ड करते हैं या क्लाइंट के पास पुराना डेटा होता है. अगर लेन-देन अस्वीकार कर दिया जाता है, तो सर्वर क्लाइंट को मौजूदा वैल्यू दिखाता है. इसके बाद, क्लाइंट अपडेट की गई वैल्यू के साथ लेन-देन को फिर से चलाता है. यह प्रोसेस तब तक दोहराई जाती है, जब तक लेन-देन स्वीकार नहीं हो जाता या कई बार कोशिश नहीं कर ली जाती.
ऑफ़लाइन डेटा सेव करना
अगर किसी क्लाइंट का इंटरनेट कनेक्शन टूट जाता है, तो भी आपका ऐप्लिकेशन ठीक से काम करता रहेगा.
Firebase डेटाबेस से कनेक्ट किया गया हर क्लाइंट, किसी भी ऐक्टिव डेटा का अपना इंटरनल वर्शन बनाए रखता है. जब डेटा सेव किया जाता है, तो वह सबसे पहले इस लोकल वर्शन में सेव होता है. इसके बाद, Firebase क्लाइंट उस डेटा को रिमोट डेटाबेस सर्वर और अन्य क्लाइंट के साथ "सबसे बेहतर तरीके" से सिंक करता है.
इस वजह से, डेटाबेस में कुछ भी लिखने पर, सर्वर में कोई डेटा लिखे जाने से पहले ही लोकल इवेंट तुरंत ट्रिगर हो जाते हैं. इसका मतलब है कि नेटवर्क की इंतज़ार की अवधि या कनेक्टिविटी की परवाह किए बिना, आपका ऐप्लिकेशन रिस्पॉन्सिव बना रहता है.
कनेक्टिविटी फिर से चालू होने पर, आपके ऐप्लिकेशन को इवेंट का सही सेट मिलता है. इससे क्लाइंट, सर्वर की मौजूदा स्थिति के साथ सिंक हो जाता है. इसके लिए, कोई कस्टम कोड लिखने की ज़रूरत नहीं पड़ती.