शुरू करने से पहले
Realtime Database का इस्तेमाल करने से पहले, Realtime Database, आपको ये काम करने होंगे:
अपने यूनिटी प्रोजेक्ट को रजिस्टर करना और उसे Firebase का इस्तेमाल करने के लिए कॉन्फ़िगर करना.
अगर आपका यूनिटी प्रोजेक्ट पहले से ही Firebase का इस्तेमाल करता है, तो वह पहले से ही Firebase के लिए रजिस्टर और कॉन्फ़िगर किया गया है.
अगर आपके पास कोई यूनिटी प्रोजेक्ट नहीं है, तो आप एक सैंपल ऐप्लिकेशन डाउनलोड कर सकते हैं.
अपने यूनिटी प्रोजेक्ट में, Firebase Unity SDK टूल (खास तौर पर,
FirebaseDatabase.unitypackage) जोड़ना.
ध्यान दें कि अपने यूनिटी प्रोजेक्ट में Firebase जोड़ने के लिए, Firebase कंसोल और खुले हुए यूनिटी प्रोजेक्ट, दोनों में टास्क पूरे करने होते हैं (उदाहरण के लिए, Firebase कंसोल से Firebase कॉन्फ़िगरेशन फ़ाइलें डाउनलोड की जाती हैं. इसके बाद, उन्हें अपने यूनिटी प्रोजेक्ट में ले जाया जाता है).
डेटा सेव करना
Firebase Realtime Database में डेटा लिखने के पांच तरीके हैं:
| तरीका | सामान्य तौर पर क्वेरी की सूची का इस्तेमाल इस तरह किया जाता है |
|---|---|
SetValueAsync() |
डेटा को तय किए गए पाथ पर लिखना या बदलना. जैसे, users/<user-id>/<username>. |
SetRawJsonValueAsync() |
रॉ Json के साथ डेटा लिखना या बदलना. जैसे, users/<user-id>/<username>. |
Push() |
डेटा की सूची में जोड़ना. `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 में बदलने के लिए, JsonUtility.ToJson() का इस्तेमाल किया जा सकता है. इसके बाद, SetRawJsonValueAsync() को कॉल किया जा सकता है.
उदाहरण के लिए, आपके पास 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() तरीके का इस्तेमाल करें.
तय किए गए Firebase रेफ़रंस में कोई नया चाइल्ड जोड़ने पर, Push() तरीका एक यूनीक कुंजी जनरेट करता है. सूची में मौजूद हर नए एलिमेंट के लिए, अपने-आप जनरेट होने वाली इन कुंजियों का इस्तेमाल करके, कई क्लाइंट एक ही जगह पर एक साथ चाइल्ड जोड़ सकते हैं. इससे लिखने से जुड़ी कोई गड़बड़ी नहीं होती. 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; } }
कोई LeaderboardEntry बनाने और उसे हाल ही के स्कोर फ़ीड और उपयोगकर्ता की अपनी स्कोर सूची में एक साथ अपडेट करने के लिए, गेम इस तरह का कोड इस्तेमाल करता है:
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); }
इस उदाहरण में, /scores/$key पर सभी उपयोगकर्ताओं की एंट्री वाले नोड में कोई एंट्री बनाने के लिए, Push() का इस्तेमाल किया गया है. साथ ही, Key की मदद से कुंजी को वापस पाया गया है. इसके बाद, कुंजी का इस्तेमाल करके, उपयोगकर्ता के स्कोर में /user-scores/$userid/$key पर दूसरी एंट्री बनाई जा सकती है.
इन पाथ का इस्तेमाल करके, JSON ट्री में कई जगहों पर एक साथ अपडेट किए जा सकते हैं. इसके लिए, UpdateChildrenAsync() को सिर्फ़ एक बार कॉल करना होता है. जैसे, इस उदाहरण में दोनों जगहों पर नई एंट्री बनाई गई है. इस तरह किए गए एक साथ अपडेट, ऐटम की तरह होते हैं. इसका मतलब है कि या तो सभी अपडेट सफल होंगे या सभी अपडेट फ़ेल होंगे.
डेटा मिटाना
डेटा मिटाने का सबसे आसान तरीका यह है कि उस डेटा की जगह के रेफ़रंस पर RemoveValue() को कॉल किया जाए.
SetValueAsync() या UpdateChildrenAsync() जैसी किसी अन्य कार्रवाई के लिए, वैल्यू के तौर पर null तय करके भी डेटा मिटाया जा सकता है. UpdateChildrenAsync() के साथ इस तकनीक का इस्तेमाल करके, एपीआई को सिर्फ़ एक बार कॉल करके, कई चाइल्ड मिटाए जा सकते हैं.
जानें कि आपका डेटा कब सेव किया गया है.
यह जानने के लिए कि आपका डेटा Firebase Realtime Database सर्वर पर कब सेव किया गया है, आप
कोई कंटीन्यूएशन जोड़ सकते हैं. SetValueAsync() और UpdateChildrenAsync(), दोनों से Task मिलता है. इससे यह पता चलता है कि कार्रवाई कब पूरी हुई. अगर किसी वजह से कॉल सफल नहीं होता है, तो Tasks IsFaulted की वैल्यू 'सही' होगी. साथ ही, 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 क्लाइंट, उस डेटा को रिमोट डेटाबेस सर्वर और अन्य क्लाइंट के साथ "बेस्ट-एफ़र्ट" के आधार पर सिंक करता है.
नतीजतन, डेटाबेस में लिखे जाने वाले सभी डेटा से जुड़े लोकल इवेंट, सर्वर पर डेटा लिखे जाने से पहले ही ट्रिगर हो जाते हैं. इसका मतलब है कि नेटवर्क की समस्या या कनेक्टिविटी न होने पर भी, आपका ऐप्लिकेशन काम करता रहता है.
कनेक्टिविटी फिर से बहाल होने के बाद, आपका ऐप्लिकेशन इवेंट का सही सेट पाता है. इससे क्लाइंट, सर्वर की मौजूदा स्थिति के साथ सिंक हो जाता है. इसके लिए, कोई कस्टम कोड लिखने की ज़रूरत नहीं होती.
अगले चरण
- अपने Realtime Database से डेटा वापस पाना
- डेटा को स्ट्रक्चर करने का तरीका जानना