强制Firebase使用缓存数据

时间:2017-02-27 07:29:25

标签: android firebase firebase-realtime-database

我想强制Firebase向我提供缓存数据,从服务器获取最新信息。这可能吗?

我们的想法是启用持久性,在特定位置调用keepSynced(true),添加一个侦听器以在数据可用时收到通知,然后调用keepSynced(false)以确保将来的侦听器获取缓存数据。

然而,在测试应用程序中,这似乎不起作用。调用keepSynced(false)不会阻止侦听器从服务器获取最新信息。 (以下代码)

使用暂时不变的Firebase数据集的正确方法是什么?

public class MainActivity extends AppCompatActivity {
  private static String TAG = "tag";
  Button keepSyncedTrue;
  Button keepSyncedFalse;
  Button getData;
  TextView data;
  private DatabaseReference myRef;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    FirebaseDatabase.getInstance().setPersistenceEnabled(true);
    myRef = getDatabaseReference();
    setContentView(R.layout.activity_main);
    keepSyncedTrue = (Button)findViewById(R.id.keepSyncTrue);
    keepSyncedFalse = (Button)findViewById(R.id.keepSyncFalse);
    getData = (Button)findViewById(R.id.getData);
    data = (TextView)findViewById(R.id.data);

    keepSyncedTrue.setOnClickListener(new View.OnClickListener() {
      @Override public void onClick(View view) {
        myRef.keepSynced(true);
      }
    });

    keepSyncedFalse.setOnClickListener(new View.OnClickListener() {
      @Override public void onClick(View view) {
        myRef.keepSynced(false);
      }
    });

    getData.setOnClickListener(new View.OnClickListener() {
      @Override public void onClick(View view) {
        // Read from the database
        myRef.addListenerForSingleValueEvent(new ValueEventListener() {
          @Override
          public void onDataChange(DataSnapshot dataSnapshot) {
            // This method is called once with the initial value and again
            // whenever data at this location is updated.
            String value = dataSnapshot.getValue(String.class);
            Log.d(TAG, "Value is: " + value);
            data.setText(value);
          }

          @Override
          public void onCancelled(DatabaseError error) {
            // Failed to read value
            Log.w(TAG, "Failed to read value.", error.toException());
          }
        });
      }
    });

  }

  private DatabaseReference getDatabaseReference() {
    return FirebaseDatabase.getInstance().getReference("message");
  }
}

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:id="@+id/activity_main"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:orientation="vertical"
    android:paddingTop="@dimen/activity_vertical_margin">


    <Button
        android:id="@+id/keepSyncTrue"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="keepSynced(true)" />

    <Button
        android:id="@+id/keepSyncFalse"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="keepSynced(false)" />

    <Button
        android:id="@+id/getData"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="get data" />

    <TextView
        android:id="@+id/data"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

2 个答案:

答案 0 :(得分:6)

这取决于你的最终目标。

如果您想避免任何类型的同步,您可以使用

DatabaseReference.goOffine();

正如您在the documentation中看到的那样:

  

手动断开Firebase数据库客户端与服务器的连接并禁用自动重新连接。

     

注意:调用此方法将影响所有Firebase数据库连接。

否则:

FirebaseDatabase.goOffline();

如上所述in doc

  

关闭与Firebase数据库后端的连接,直到调用goOnline()

如果您希望保持同步并使用可以使用的本地缓存数据,请转到:

FirebaseDatabase.getInstance().setPersistenceEnabled(true);

正如文档中所述:

  

通过启用持久性,即使用户或操作系统重新启动应用程序,Firebase实时数据库客户端在联机时将同步的任何数据都会保留到磁盘并可脱机使用。这意味着您的应用程序可以像使用存储在缓存中的本地数据一样在线工作。监听器回调将继续触发本地更新。

在这种情况下,您的应用程序使用缓存数据,但客户端继续与服务器数据同步 More info here.

同样在这种情况下,要保持特定位置同步使用:

yourRef.keepSynced(true);

答案 1 :(得分:0)

您可以在应用中启用Disk Persistence来使用Firebase离线功能。这就是它的完成方式:

public class MyApp extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        if (!FirebaseApp.getApps(this).isEmpty()) {
            FirebaseDatabase.getInstance().setPersistenceEnabled(true);
        }
    }
}

启用磁盘持久性后,Firebase侦听器将查找以DataSnapshot为基础缓存数据优先。因此,为了防止它从服务器获取数据,每次要读取数据时都应使用Firebase addListenerForSingleValueEvent,因为它只会读取一次并在此之后自行删除,这意味着它会读取来自缓存数据。

我认为你不需要在这种情况下使用keepSynced(boolean value)