如何处理Firebase离线模式和数据推送? [英] How deal with Firebase offline mode and data push?
问题描述
使用Firebase时,建议使用push()命令管理数据列表。但是,当Firebase进入离线状态(goOffline或NetworkOffline)时,如果应用程序尝试使用推送一个列表中的数据,完成监听器不会被触发,直到应用程序返回在线:所以没有唯一的ID,直到线再次打开。
1 /这是预期的/正常的行为?/ b>
3我的用例处理与自己的关系的数据。这意味着我想创建一个对象),然后重用这个主对象id(由完成监听器提供)来建立主对象和所有其他相关对象之间的关系,如何处理这个离线状态? b
$ b
代码示例:
findViewById(R.id。 button3).setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){$ b $ new Firebase(getString(R.string.firebase_url))。child( ();}}。push()。setValue(counter ++,new Firebase.CompletionListener(){
@Override $ b $ public void onComplete(firebaseError firebaseError,firebase firebase){
((TextView)findViewById (String.valueOf(counter)+ - + firebase.toString());
}
});
}
});
编辑 p>这里有4种添加数据的方式:
用监听器推送
findViewById(R.id.button3).setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
new Firebase(getString(R.string.firebase_url))。child(stack)。push()。setValue(counter ++,new Firebase.CompletionListener(){
@Override $ b $ public void onComplete(FirebaseError firebaseError ,Firebase firebase){
((TextView)findViewById(R.id.textView3))。setText(String.valueOf(counter)+ - + firebase.toString());
}
});
}
});
SetValue with Listener
findViewById(R.id.button4).setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
new Firebase(getString(R.string.firebase_url))。child(stackManual)。child(UUID.randomUUID()。toString())。setValue(counter ++,new Firebase.CompletionListener(){
@Override
public void onComplete(FirebaseError firebaseError,Firebase firebase){
((TextView)findViewById(R.id.textView4))。setText(String.valueOf(counter)+ - + firebase .toString());
}
});
}
});
无监听器的SetValue
findViewById(R.id.button5).setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
Firebase temp = new Firebase(getString(R.string.firebase_url))。child(stackManual)。child(UUID.randomUUID()。toString());
temp.setValue(counter ++); ((TextView)findViewById(R.id.textView5))。setText(String.valueOf(counter)+ - + temp.getKey()。toString());
}
});
无监听器
findViewById(R.id.button6).setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
Firebase temp = new Firebase(getString(R.string.firebase_url))。child(stack)。push();
temp.setValue(counter ++);
(TextView)findViewById(R.id.textView6))。setText(String.valueOf(counter)+ - + temp.getKey()。toString());
}
});
它会触发监听器,只有当数据位于服务器上的数据库中时,才会触发在本地数据库!
- 是否正确?
- 是否被记录?
因为知道,一个简单的异步应用程序现在更难构建:异步作业封装可能不会在离线时执行,可以吗?
),解决方案似乎是︰
- 使用push()命令创建一个唯一的ID
- 在(1)中添加一个监听器(单值)到之前创建的节点的firebase引用中。
-
在侦听器中安排你的工作(这里更新UI,但可能是另一个命令)
$ $ p $ code findViewById(R.id.button7).setOnClickListener(new View.OnClickListener(){
@覆盖
public void onClick(View v){
Firebase temp = new Firebase(getString(R.string.firebase_url))。child(stack)。push();
temp。 addListenerForSingleValueEvent(new ValueEventListener(){
@Override
public void onDataChange(DataSnapshot dataSnapshot){
((TextView)findViewById(R.id.textView7))。setText(String.valueOf(counter)+ - + dataSnapshot.getKey ()的ToString());
}
@Override
public void onCancelled(FirebaseError firebaseError){
$ b}
});
temp.setValue(counter ++);
}
});
When using Firebase, it is recommanded to use the push() command to manage data list. That's really fine, it provides a unique and ordered id for data pushed on the list.
However, when Firebase goes offline (goOffline or NetworkOffline), if the app try to push a data on a list, the completion listener is not triggered, until the app goes back online : so there is no unique id until the line is on again.
1/ Is that the expected/normal behavior ?
2/ I didn"t see in the document (as far I remember), that the push command is working differently (or only in onlinemode) in offline state. Did I miss a line somewhere ?
3/ My use case deal with data that own relationship. It means I want create an object (kind of master) in a list, and then reuse this master object id (provided by the completion listener) to build the relation between the master object and all other relevants objects. How may I deal with this offline state ?
Code Example :
findViewById(R.id.button3).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Firebase(getString(R.string.firebase_url)).child("stack").push().setValue(counter++, new Firebase.CompletionListener() {
@Override
public void onComplete(FirebaseError firebaseError, Firebase firebase) {
((TextView) findViewById(R.id.textView3)).setText(String.valueOf(counter) + " - " + firebase.toString());
}
});
}
});
Edit
Here is 4 ways to add data:
Push with Listener
findViewById(R.id.button3).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Firebase(getString(R.string.firebase_url)).child("stack").push().setValue(counter++, new Firebase.CompletionListener() {
@Override
public void onComplete(FirebaseError firebaseError, Firebase firebase) {
((TextView) findViewById(R.id.textView3)).setText(String.valueOf(counter) + " - " + firebase.toString());
}
});
}
});
SetValue with Listener
findViewById(R.id.button4).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Firebase(getString(R.string.firebase_url)).child("stackManual").child(UUID.randomUUID().toString()).setValue(counter++, new Firebase.CompletionListener() {
@Override
public void onComplete(FirebaseError firebaseError, Firebase firebase) {
((TextView) findViewById(R.id.textView4)).setText(String.valueOf(counter) + " - " + firebase.toString());
}
});
}
});
SetValue without Listener
findViewById(R.id.button5).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Firebase temp = new Firebase(getString(R.string.firebase_url)).child("stackManual").child(UUID.randomUUID().toString());
temp.setValue(counter++);
((TextView) findViewById(R.id.textView5)).setText(String.valueOf(counter) + " - " + temp.getKey().toString());
}
});
Push without Listener
findViewById(R.id.button6).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Firebase temp = new Firebase(getString(R.string.firebase_url)).child("stack").push();
temp.setValue(counter++);
((TextView) findViewById(R.id.textView6)).setText(String.valueOf(counter) + " - " + temp.getKey().toString());
}
});
IT APPEAR THAT THE LISTENERS ARE TRIGGERED ONLY WHEN THE DATA ARE IN THE DATABASE ON THE SERVER, AND NOT ON THE LOCAL DB ! - IS THAT CORRECT ? - IS THAT DOCUMENTED ?
Because knowing that, a straight forward asynchronous application is more difficult to build now : encapsulation of asynchronous job may not be performed if offline, may it ?
Following what @Andrew-lee and @Frank-fan-puffelen (thank to both agree on that please), the solution appear to be :
- Create a unique id with push() command
- Add a listener (Single Value) to a firebase ref of the previous created node in (1.)
Schedule your job inside the listener (here update the UI, but could be another command)
findViewById(R.id.button7).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Firebase temp = new Firebase(getString(R.string.firebase_url)).child("stack").push(); temp.addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { ((TextView) findViewById(R.id.textView7)).setText(String.valueOf(counter) + " - " + dataSnapshot.getKey().toString()); } @Override public void onCancelled(FirebaseError firebaseError) { } }); temp.setValue(counter++); } });
这篇关于如何处理Firebase离线模式和数据推送?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!