【问题标题】:How to store data offline and then upload later in the firebase when app has internet access?当应用程序可以访问互联网时,如何离线存储数据然后在 Firebase 中上传?
【发布时间】:2022-01-04 12:12:13
【问题描述】:

我正在创建一个应用程序,它接受用户的输入并上传到 Firebase。如果该应用程序可以访问互联网,则该应用程序可以正常工作。但是如果应用无法访问互联网,我想让我的应用接受输入并离线存储这些数据,然后在应用可以访问互联网时上传到 Firebase。

我也使用“磁盘持久性

FirebaseDatabase.getInstance().setPersistenceEnabled(true);

还有“保持数据新鲜

DatabaseReference scoresRef = FirebaseDatabase.getInstance().getReference("scores");
scoresRef.keepSynced(true);

但这对我不起作用。也许我没有正确使用它。

我的代码是

AddDataActivity

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    binding = ActivityAddDataBinding.inflate(getLayoutInflater());
    setContentView(binding.getRoot());
    Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);
    getSupportActionBar().setTitle("Add Data");
    FirebaseDatabase database = FirebaseDatabase.getInstance();
    database.getReference().child("Users").child(FirebaseAuth.getInstance().getUid()).child("data_added_by_user").keepSynced(true);
    progressDialog = new ProgressDialog(AddDataActivity.this);
    progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
    progressDialog.setTitle("Adding Data");
    progressDialog.setMessage("Please Wait ...");
    progressDialog.setCancelable(false);
    progressDialog.setCanceledOnTouchOutside(false);

    Intent mintent = getIntent();
    String activity = mintent.getStringExtra("activity");
    if (activity.equals("list")){
        String date = mintent.getStringExtra("date");
        String name = mintent.getStringExtra("name");
        String weight = mintent.getStringExtra("weight");
        String rate = mintent.getStringExtra("rate");
        binding.editDate.setText(date);
        binding.editName.setText(name);
        binding.editWeight.setText(weight);
        binding.editRate.setText(rate);
    }





    binding.btnSubmit.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (binding.editDate.getText().toString().length() == 0) {
                Toast.makeText(AddDataActivity.this, "Enter Date", Toast.LENGTH_SHORT).show();
            } else if (binding.editName.getText().toString().length() == 0) {
                Toast.makeText(AddDataActivity.this, "Enter Name", Toast.LENGTH_SHORT).show();

            } else if (binding.editWeight.getText().toString().length() == 0) {
                Toast.makeText(AddDataActivity.this, "Enter Weight", Toast.LENGTH_SHORT).show();

            } else {
                if (notValidDateFormat(binding.editDate.getText().toString(), "yyyy-MM-dd")
                        || notValidDateFormat(binding.editDate.getText().toString(), "yyyy/MM/dd")
                        || notValidDateFormat(binding.editDate.getText().toString(), "yyyy.MM.dd")){

                    progressDialog.show();
                    DataModel data = new DataModel();
                    int weight = Integer.parseInt(binding.editWeight.getText().toString());
                    int rate = Integer.parseInt(binding.editRate.getText().toString());
                    data.setDate(binding.editDate.getText().toString());
                    data.setName(binding.editName.getText().toString());
                    data.setWeight(weight);
                    data.setRate(rate);
                    data.setAddedBy(FirebaseAuth.getInstance().getUid());
                    if (!activity.equals("list")) {
                        data.setAddedTime(new Date().getTime());
                        data.setSell(true);
                        String dataId = database.getReference().child("Users").child(FirebaseAuth.getInstance().getUid()).child("data_added_by_user").push().getKey();
                        data.setDataId(dataId);
                        database.getReference().child("Users").child(FirebaseAuth.getInstance().getUid()).child("data_added_by_user").child(dataId).setValue(data)
                                .addOnSuccessListener(new OnSuccessListener<Void>() {
                                    @Override
                                    public void onSuccess(Void unused) {
                                        progressDialog.dismiss();
                                        Toast.makeText(AddDataActivity.this, "Data Added!", Toast.LENGTH_SHORT).show();
                                        Intent intent = new Intent(AddDataActivity.this, ItemListActivity.class);
                                        startActivity(intent);
                                        finish();
                                    }
                                });
                    } else{
                        database.getReference().child("Users").child(FirebaseAuth.getInstance().getUid()).child("data_added_by_user").child(mintent.getStringExtra("id")).child("modifiedTime").setValue(new Date().getTime());
                        database.getReference().child("Users").child(FirebaseAuth.getInstance().getUid()).child("data_added_by_user").child(mintent.getStringExtra("id")).child("date").setValue(binding.editDate.getText().toString());
                        database.getReference().child("Users").child(FirebaseAuth.getInstance().getUid()).child("data_added_by_user").child(mintent.getStringExtra("id")).child("name").setValue(binding.editName.getText().toString());
                        database.getReference().child("Users").child(FirebaseAuth.getInstance().getUid()).child("data_added_by_user").child(mintent.getStringExtra("id")).child("weight").setValue(weight);
                        database.getReference().child("Users").child(FirebaseAuth.getInstance().getUid()).child("data_added_by_user").child(mintent.getStringExtra("id")).child("rate").setValue(rate)
                                .addOnSuccessListener(new OnSuccessListener<Void>() {
                                    @Override
                                    public void onSuccess(Void unused) {
                                        progressDialog.dismiss();
                                        Toast.makeText(AddDataActivity.this, "Data Modified!", Toast.LENGTH_SHORT).show();
                                        Intent intent = new Intent(AddDataActivity.this, ItemListActivity.class);
                                        startActivity(intent);
                                        finish();
                                    }
                                });
                    }

                } else {
                    Toast.makeText(AddDataActivity.this, "Invalid Date Format! ", 
       Toast.LENGTH_SHORT).show();
                }
            }
        }

    });


}

对于磁盘持久性,我创建了与项目名称相同的新java类

public class PhoNote extends Application {

@Override
public void onCreate() {
    super.onCreate();
    FirebaseDatabase.getInstance().setPersistenceEnabled(true);
  }
}

谢谢!!

【问题讨论】:

  • “但这对我不起作用。”没有提供足够的信息,所以我们可以提供帮助。这段代码中究竟有什么不能按您期望的方式工作?告诉我们共享代码有什么问题。你有什么错误吗?
  • @AlexMamo 如果应用程序可以访问互联网,则此代码可以正常工作。问题不在于这段代码。我只想在我的应用程序中实现离线功能。如何实施?
  • @Regmi 这留下了同样的问题:what 对您共享的代码不起作用?
  • @FrankvanPuffelen 当应用程序无法访问 Internet 时,如果我按 btnSubmit 它会显示进度对话框但永远不会关闭。

标签: android firebase firebase-realtime-database


【解决方案1】:

在写入数据库时​​,Firebase 不会将缺少互联网连接视为错误情况。相反,它会在这种情况下将数据保存在内存中(如果您enabled disk persistence,也将数据保存在磁盘上)并在重新建立连接时将其同步到服务器。

当您将完成侦听器或成功侦听器附加到写入操作时,只有在服务器上提交或拒绝操作时才会触发。在某些情况下这可能很重要,但在大多数情况下您实际上并不需要

这意味着在大多数情况下,在对 Firebase 进行写入操作时,您不需要完成侦听器,甚至不需要进度对话框。相反,您应该将它们视为本地的、即时的并且在 setValue() 调用执行时完成。

所以:

database.getReference().child("Users").child(FirebaseAuth.getInstance().getUid()).child("data_added_by_user").child(dataId).setValue(data);

Toast.makeText(AddDataActivity.this, "Data Added!", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(AddDataActivity.this, ItemListActivity.class);
startActivity(intent);
finish();

【讨论】:

  • 这解决了进度对话框关闭问题,但在重新建立连接时不会将输入的数据同步到服务器。
  • 一旦重新建立连接,挂起的写入应该自动同步。这不是发生在你身上吗?
  • 是的,这不会发生。如果你想要完整的项目Here是github链接
  • 相反,您可以enable debug logging 并检查 logcat 是否显示 Firebase 在这种情况下重新连接到数据库?
  • 我终于成功了。非常感谢。
猜你喜欢
  • 2018-04-28
  • 2016-12-13
  • 1970-01-01
  • 2016-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-30
  • 1970-01-01
相关资源
最近更新 更多