2016-06-14 5 views
1

私はfirebaseを使用して、モバイルゲーム用のグローバルリーダーボードとソーシャルリーダーボードを構築しています。ゲームにはハイスコアのエントリの1000sの10sがあるので、エントリの完全なリストをロードすることは推奨されませんので、ページネーションを使用します。 しかし、私はリスト全体をロードせずに現在のプレイヤーの位置をロードします。firebaseで完全なリストを取得せずにリスト内のノードのインデックス/位置を取得する方法は?

例:リーダーボードは100人、ユーザーXYZは65位です。リスト全体をロードせずに65を得る方法はありますか?

+0

ページネーションを実装したり、指定された条件でアイテムを取得したりするのはどうですか? [1](https://www.firebase.com/docs/web/api/query/limittofirst.html) [For 2](https://www.firebase.com/docs/web/api) /query/equalto.html) –

+0

@Rohit Goyal、解決策を見つけましたか? – JCarlos

答えて

1

特定のキーのインデックスを知る方法がなく、すべてのキーをダウンロードする必要はありません。これは、FirebaseのAPIとよく一致しない操作で、主にデータベースのリアルタイム性のためです。

+3

こんにちは@Frank Firebaseで働くと、Firebaseがリーダーボードに使われていると思いますか?はいの場合、人々はこの挑戦をどのように扱いますか? Firebase側からこの問題に対処する予定もありますか? –

1

これは簡単な解決策ではありません。あなたはn番目の項目を返すために探しているなら、この記事は役に立つかもしれません:Can I get the nth item of a firebase "query"?

しかし、あなたは間違いなくyourRef.orderByChild('points').limitToFirst(65)のようなトップ65何かを返すようにORDERBYとlimitToFirstを使用して、リスト全体をロードせずにこれを行うことができます。

おそらくあなたが望んでいたほど簡単ではないかもしれませんが、それが助けてくれることを願っています。

+0

私はn番目の項目を取得したくない、私は特定のユーザーのnを取得したい。 –

+0

私はこれのための素晴らしい解決策を知らない。あなたは潜在的にデータを非正規化し、単にユーザーのアイデアとスコアを保存することができます。そうすれば、そのデータをすべて呼び出す必要がありますが、回答を見つけるためにはかなりのデータを返す必要はありません。 別の方法として、各プレーヤーの「ランク」プロパティを更新するCronプロセスを実行することがあります。現在のランクに即座にアクセスすることはできませんが、アイデアが毎日更新されているのであれば、ユーザーベースが増えるにつれて大量のデータを返す必要はありません。 –

1

これは非常に簡単な回答かもしれませんが、実際にデータをどのように構成するかによって大きく変わります。

常に100人のユーザーがいて、65歳から1歳までのすべてのユーザーには、簡単にアクセスできます。

同様に、ユーザーXYZの位置を希望する場合は、これも簡単です。 /ユーザー/位置による位置ソート上のクエリに続い

位置(または35)で、トップ2のユーザーをロードする方法もあります

users: 
    user_id_0 
    position: 15 
    user_id_1 
    position: 32 
    user_id_2 
    position: 7 

、その後queryLimitedToFirstは(2)user_id_2とuser_id_0を返します。 。

編集:より多くのデータに基づいて

、ここではカップルより多くのオプションがあります。あなたがuid_2のスコアに基づいて位置を知りたい場合は、我々は5人のユーザー、スコアと各(私は、リスト内の自分の立場」を指摘)

uid_0: 50 //pos 2 
uid_1: 25 //pos 1 
uid_2: 73 //pos 4 
uid_3: 10 //pos 0 
uid_4: 58 //pos 3 

を持って考える - 私はあなたのプラットフォームを知りません私は、一般的な流れ与える:

、その後、彼のスコア、73を取得するためにステップ2)queryOrderedByChild(スコア).startingAtValue(73)

ステップ1)クエリuid_2を、73から何にスコアでノードを取得最高得点は

手順3です)結果はスナップショットになりますので、sn apshot.childrenCount、uid_2の位置は4になります。これにより、ロードされるノードの数が減ります。

リストが遠いほど、データが多くロードされるという欠点があります。スコアだけのノードが1000個しかない場合、それは大量のデータではありません。

次の解決策では、大量のデータを回避できますが、アプリケーションによって多くの作業が必要になります。

もちろん、ご使用のプラットフォームがアレイをサポートしている場合、これは超簡単な作業です。上の同じ構造体を使用して、子を配列に配列し、位置を知りたいuidのインデックス番号を取得します。

スウィフトコード

let ref = self.myRootRef.childByAppendingPath("scores") 
ref.queryOrderedByValue().observeEventType(.Value, withBlock: { snapshot in 

    var myArray = [String]() 

    for child in snapshot.children { 
      let key = child.key as String 
      myArray.append(key) 
    } 

    let pos = myArray.indexOf("uid_0") 
    print("postion = \(pos!)") 
}) 
+0

あなたがやっていることは、特定の位置で値を取得したい場合です。しかし、問題は私が選手の位置を知らないということです。 たとえば、リーダーボードに1000人のプレーヤーがいる場合、動的な2つのものがあります 1)合計プレーヤー数 2)各プレーヤーの得点 –

+0

@RohitGoyalあなたの質問には、あなたは言っています。現在のプレイヤーはリスト全体を読み込まずに*スコアはスコアと同じですか?そうでなければ、関係は何ですか? – Jay

+0

だから、usernameがキー、スコアが値です。リーダーボードのユーザーのランクをスコア別に知りたい とにかくFirebaseのFrankは、今のところFirebaseではそれができないと答えました。 –

0

一つの方法は、各プレイヤーのための「ランク」プロパティを更新プロセスを実行するかもしれません。現在のランクに即座にアクセスすることはできませんが、アイデアが毎日更新されているか定期的に予定されているタイミングであれば、それは大量のデータをユーザーベースの拡大に伴いプロセスは、n番目の項目を取得するため@pufs勧告のようなものが考えられます。

var ref = new Firebase('https://yours.firebaseio.com/users'); 
var lastKnownScore = null; 
var firstQuery = ref.orderByChild('points').limitToFirst(100); 
var newRank = 1; 
firstQuery.once('value', function(snapshot) { 
    snapshot.forEach(function(childSnapshot) { 
    childSnapshot.update({ rank: newRank }); 
    lastKnownScore = childSnapshot.value(); 
    newRank++; 
    }); 
}); 

while(lastKnownScore > 0) { 
    var nextQuery = ref.orderByChild('points').startAt(lastKnownScore).limitToFirst(100); 

    nextQuery.once('value', function(snapshot) { 
    snapshot.forEach(function(childSnapshot) { 
     childSnapshot.update({ rank: newRank }); 
     lastKnownScore = childSnapshot.value(); 
     newRank++; 
    }); 
    }); 
} 

あなたは、複数のプレイヤーが0のポイントを持っているかもしれません同じスコアや選手がいることを期待する場合、これは、いくつかのリファクタリングが必要になりますが、うまくいけば、あなたは何を見ることができます私はやっている。このコードを定期的に実行するプロセスを設定すると、ランクを比較的最新の状態に保つことができます。

関連する問題