【问题标题】:Database push in Firebase not working in android if i close my app, firebase bug如果我关闭我的应用程序,Firebase 中的数据库推送在 android 中不起作用,firebase 错误
【发布时间】:2017-08-29 04:13:10
【问题描述】:
public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";

    public static final String ANONYMOUS = "anonymous";
    public static final int RC_SIGN_IN = 1;
    private static final int RC_PHOTO_PICKER = 2;
    private String mUsername;

    // Firebase instance variables
    private FirebaseDatabase mFirebaseDatabase;
    private DatabaseReference mMessagesDatabaseReference;
    private ChildEventListener mChildEventListener;
    private FirebaseAuth mFirebaseAuth;
    private FirebaseAuth.AuthStateListener mAuthStateListener;
    private FirebaseStorage mFirebaseStorage;
    private StorageReference mChatPhotosStorageReference;

    private SeekBar seekBar;

    private RecyclerView recyclerView;
    private FloatingActionButton floatingActionButton;
    NotificationCompat.Builder notificationBuilder;
    VideoAdapter videoAdapter;
    List<Video> videoList;


    NotificationManager notificationManager;
    AlertDialog.Builder alertDialog;
    EditText input;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mUsername = ANONYMOUS;
        recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
        floatingActionButton = (FloatingActionButton) findViewById(R.id.floatingactionbutton);
        videoList = new ArrayList();
        // Initialize Firebase components
        mFirebaseDatabase = FirebaseDatabase.getInstance();
        mFirebaseAuth = FirebaseAuth.getInstance();
        mFirebaseStorage = FirebaseStorage.getInstance();
        seekBar = (SeekBar) findViewById(R.id.seekbar);

        mMessagesDatabaseReference = mFirebaseDatabase.getReference().child("videomessages");
        mChatPhotosStorageReference = mFirebaseStorage.getReference().child("videos");

        mAuthStateListener = new FirebaseAuth.AuthStateListener() {
            @Override
            public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
                FirebaseUser user = firebaseAuth.getCurrentUser();
                if (user != null) {
                    // User is signed in
                    onSignedInInitialize(user.getDisplayName());
                } else {
                    // User is signed out
                    onSignedOutCleanup();
                    startActivityForResult(
                            AuthUI.getInstance()
                                    .createSignInIntentBuilder()
                                    .setIsSmartLockEnabled(false)
                                    .setProviders(
                                            AuthUI.EMAIL_PROVIDER,
                                            AuthUI.GOOGLE_PROVIDER)
                                    .build(),
                            RC_SIGN_IN);
                }
            }
        };





        floatingActionButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
                intent.setType("video/*");
                intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
                startActivityForResult(Intent.createChooser(intent, "Complete action using"), RC_PHOTO_PICKER);


            }
        });


        attachDatabaseReadListener();
 }


    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == RC_SIGN_IN) {
            if (resultCode == RESULT_OK) {
                // Sign-in succeeded, set up the UI
                Toast.makeText(this, "Signed in!", Toast.LENGTH_SHORT).show();
            } else if (resultCode == RESULT_CANCELED) {
                // Sign in was canceled by the user, finish the activity
                Toast.makeText(this, "Sign in canceled", Toast.LENGTH_SHORT).show();
                finish();
            }
        } else if (requestCode == RC_PHOTO_PICKER && resultCode == RESULT_OK) {
            final Uri selectedImageUri = data.getData();

            String uriString = selectedImageUri.toString();
            File myFile = new File(uriString);
            String path = myFile.getAbsolutePath();
            String displayName = null;

            if (uriString.startsWith("content://")) {
                Cursor cursor = null;
                try {
                    cursor = getApplicationContext().getContentResolver().query(selectedImageUri, null, null, null, null);
                    if (cursor != null && cursor.moveToFirst()) {
                        displayName = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
                    }
                } finally {
                    cursor.close();
                }
            } else if (uriString.startsWith("file://")) {
                displayName = myFile.getName();
            }

            alertDialog = new AlertDialog.Builder(MainActivity.this);
            alertDialog.setTitle("Upload");
            alertDialog.setMessage("Enter Name");

            input = new EditText(MainActivity.this);
            LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.MATCH_PARENT,
                    LinearLayout.LayoutParams.MATCH_PARENT);
            input.setLayoutParams(lp);
            input.setText(displayName);
            alertDialog.setView(input);

            alertDialog.setPositiveButton("YES",
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {


                            new MyAsyncTask().execute(selectedImageUri);

                        }});

            alertDialog.setNegativeButton("NO",
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.cancel();
                        }
                    });

            alertDialog.show();



        }

    }

    @Override
    protected void onResume() {
        super.onResume();
        mFirebaseAuth.addAuthStateListener(mAuthStateListener);
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mAuthStateListener != null) {
            mFirebaseAuth.removeAuthStateListener(mAuthStateListener);
        }
    }

    private void onSignedInInitialize(String username) {
        mUsername = username;
        attachDatabaseReadListener();
    }

    private void onSignedOutCleanup() {
        mUsername = ANONYMOUS;

    }

    private void attachDatabaseReadListener() {

        mMessagesDatabaseReference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot snapshot) {
                videoList.clear();
                for (DataSnapshot postSnapshot : snapshot.getChildren()) {

                    Video postSnapshotValue = postSnapshot.getValue(Video.class);
                    if (!videoList.contains(postSnapshotValue)) {
                        videoList.add(postSnapshotValue);
                        Log.i(TAG, "onDataChange: " + videoList);
                    }

                }

                videoAdapter = new VideoAdapter(videoList, MainActivity.this);
                recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));

                recyclerView.setAdapter(videoAdapter);

            }

            @Override
            public void onCancelled(DatabaseError databaseError) {


            }
        });
    }


    public class MyAsyncTask extends AsyncTask<Uri, Void, Void> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

        }

        @Override
        protected Void doInBackground(final Uri... params) {
            final StorageReference photoRef = mChatPhotosStorageReference.child(params[0].getLastPathSegment());
            alertDialog.setView(input);

                photoRef.putFile(params[0])
                                    .addOnSuccessListener(MainActivity.this, new OnSuccessListener<UploadTask.TaskSnapshot>() {
                                        public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                                            // When the image has successfully uploaded, we get its download URL
                                            //  progressBar.setVisibility(View.VISIBLE);
                                            Uri downloadUrl = taskSnapshot.getDownloadUrl();
                                            //String nameUrl=taskSnapshot.getMetadata().getName();

                                            Video video = new Video(input.getText().toString().trim(),downloadUrl.toString());
                                            Log.i(TAG, "onSuccess: Video Uploaded");
                                            mMessagesDatabaseReference.push().setValue(video);
                                         //   mMessagesDatabaseReference.push().setValue(video.getVideoUrl());

                                        }
                                    }).addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
                                @Override
                                public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
                                    int  progress = (int) ((100 * taskSnapshot.getBytesTransferred()) / taskSnapshot.getTotalByteCount());

                                    seekBar.setProgress(progress);

                                    notificationBuilder = new NotificationCompat.Builder(getApplicationContext())
                                            .setColor(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimary))
                                            .setSmallIcon(R.mipmap.ic_launcher)
                                            .setContentText("Upload in progress")
                                            .setContentIntent(contentIntent(getApplicationContext()))
                                            .setAutoCancel(true);

                                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                                        notificationBuilder.setPriority(Notification.PRIORITY_HIGH);
                                    }

                                    notificationManager = (NotificationManager)
                                            getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);

                                    for (int incr = progress; incr <= 100; incr += 5) {


                                        notificationBuilder.setProgress(100, progress, false);

                                        notificationManager.notify(20, notificationBuilder.build());

                                    }
                                    if(progress>=100){
                                        notificationBuilder.setContentText("Upload complete").setProgress(0, 0, false);
                                        notificationManager.notify(20, notificationBuilder.build());

                                    }



                                }
                            });




           return null;
        }


    }

    private PendingIntent contentIntent(Context context) {

        Intent startActivityIntent = new Intent(context, MainActivity.class);
        return PendingIntent.getActivity(
                context,
                0,
                startActivityIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);
    }





}

我正在通过单击浮动操作按钮将视频上传到 Firebase 存储。视频成功上传到存储。当视频上传时,我使用以下代码将视频名称及其下载 url 推送到数据库

Video video = new Video(input.getText().toString().trim(),downloadUrl.toString());
                                            Log.i(TAG, "onSuccess: Video Uploaded");
                                            mMessagesDatabaseReference.push().setValue(video);

我猜这是firebase 中的一个错误。我不确定,但请听我说完。 第一种情况: 当我将我的视频上传到firebase 并保持我的应用程序打开直到视频上传时,视频名称和下载url 被推送到firebase 数据库并且视频被上传到存储。 第二种情况: 如果我将视频上传到firebase 存储并打开其他应用程序,例如youtube,并且在我的通知中,我会收到有关上传视频的数量以及上传完整视频后是否再次打开我的应用程序的通知, firebase 不会将名称和视频 url 推送到数据库,而是将视频上传到存储中。 为什么会出现这种行为?谁能指导我..

【问题讨论】:

  • 对于第二种(失败)情况,你看到logcat消息onSuccess: Video Uploaded了吗?
  • @BobSnyder 是的。

标签: android firebase firebase-realtime-database firebase-storage


【解决方案1】:

更新:

您正在photoRef.putFile(params[0]) 上使用活动范围的成功侦听器。 The documentation 解释:

在 onStop() 期间监听器会被自动移除

当您的 Activity 进入后台时,它会停止并移除侦听器。使用不将 Activity 作为第一个参数的 addOnSuccessListener() 的另一种形式。


为嫌疑人setValue() 添加一个完成侦听器。另外,记录input 的值。我不确定当 Activity 停止时 UI 对象的状态会发生什么变化。

Video video = new Video(input.getText().toString().trim(),downloadUrl.toString());
Log.i(TAG, "onSuccess: Video Uploaded= " + input.getText());
mMessagesDatabaseReference.push().setValue(video, new DatabaseReference.CompletionListener() {
    @Override
    public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
        if (databaseError == null) {
            Log.d(TAG, "onComplete: SUCCESS");
        } else {
            Log.e(TAG, "onComplete: FAILED ", databaseError.toException());
        }
    }
});

根据对 cme​​ts 的响应,听起来您的活动在进入后台时可能会被破坏(而不是停止)。将此方法和日志语句添加到您的活动中以查看是否正在发生:

@Override
protected void onDestroy() {
    super.onDestroy();
    Log.i(TAG, "onDestroy: ");
}

【讨论】:

  • @BobSynder 在我的项目中添加你的代码后,同样的事情会发生。如果我开始上传,保持我的应用程序打开,我可以看到 Log.i(TAG, "onSuccess: Video Uploaded=" + input.getText());,上传视频并将值推送到数据库。如果我在上传时关闭我的应用程序,我无法看到任何日志语句,尽管视频已上传到 Firebase 存储但没有值被推送到数据库
  • 当你说“关闭我的应用程序”时,你的意思是你把它放在后台,例如进入主屏幕?在这种情况下,您应该继续看到应用程序的日志输出。您在之前的回复中指出,当应用程序关闭时您会看到 onSuccess: Video Uploaded 日志消息。对吗?
  • 添加onDestroy() 方法,如我更新的答案所示。
  • 当我的应用在后台时,永远不会调用 onDestroy 的 Log.i
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-13
  • 2019-03-12
相关资源
最近更新 更多