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