Перезапустите запланированные уведомления (которые требуют данных Firebase) после перезагрузки устройства - PullRequest
0 голосов
/ 05 октября 2018

Мое приложение в настоящее время планирует уведомления для задач в определенное время (по выбору пользователя).Название задачи и дата напоминания сохраняются в базе данных Firebase Realtime.

Дело в том, что при перезагрузке устройства все это теряется.Поэтому необходимо перезапустить все соответствующие уведомления, которые были запланированы в прошлом.

Поэтому у меня есть BroadcastReceiver, который может получить намерение BOOT_COMPLETED.Тем не менее, я не могу получить доступ к базе данных Firebase, потому что ни один пользователь в настоящее время не вошел в систему - и я также не могу запустить проверку подлинности Firebase (startActivityForResult не распознается, и импорт вызывает больше ошибок).Я предполагаю, что это потому, что BroadcastReceiver не является деятельностью.

Мне интересно, есть ли способ обойти это.В настоящее время я попытался установить намерение запустить MainActivity (где пользователь аутентифицирован), а затем выполнить мои соответствующие задачи, однако это не сработало.

Мне интересно, есть ли способ обойти это, чтобы получитьаутентифицированный пользователь (или аутентифицировать его при перезагрузке устройства), а затем получить данные из Firebase.

Код AlarmReceiver (расширяет BroadcastReceiver) - это немного беспорядок, но помогает получить контекст.

public class AlarmReceiver extends BroadcastReceiver  {

private ChildEventListener mChildEventListener;
private FirebaseDatabase mFirebaseDatabase;
private DatabaseReference mTaskDatabaseReference;
private FirebaseAuth mFirebaseAuth;
private FirebaseAuth.AuthStateListener mAuthStateListener;
private int i;

@Override
public void onReceive(final Context context, Intent intent) {
    mFirebaseDatabase = FirebaseDatabase.getInstance();
    mFirebaseAuth = FirebaseAuth.getInstance();

    if (intent.getAction() != null && context != null) {
        if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
            TaskInfoFragment.showReminderNotification(context, MainActivity.class, "hoooo",1000);
            onSignedOutCleanup(context);
            mTaskDatabaseReference=mFirebaseDatabase.getReference().child("users").child(MainActivity.getCurrentUserId());
            attachDatabaseReadListener(context);
            //TODO - HANDLE DEVICE REBOOT

        }
    }


    //Trigger the notification
    Bundle extras = intent.getExtras();
    String taskTitle = "Error, no task title!";
    int taskIntId=-1;
    if (extras != null) {
        taskTitle = extras.getString("taskTitle");
        taskIntId=extras.getInt("taskIntId");
    }

    TaskInfoFragment.showReminderNotification(context, MainActivity.class, taskTitle,taskIntId);

}

private void attachDatabaseReadListener(final Context context) {
      i=0;

        mChildEventListener = new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                i++;
                TaskList task = dataSnapshot.getValue(TaskList.class);
                TaskInfoFragment.showReminderNotification(context, MainActivity.class, task.getTitle(),i);
                Log.d("here is another task","title: "+task.getTitle());
            }
            public void onChildChanged(DataSnapshot dataSnapshot, String s) {}
            public void onChildRemoved(DataSnapshot dataSnapshot) {
            }
            public void onChildMoved(DataSnapshot dataSnapshot, String s) {}
            public void onCancelled(DatabaseError databaseError) {}
        };

        mTaskDatabaseReference.addChildEventListener(mChildEventListener);

}

private void onSignedInInitialize(final String userId,Context context) {

    //Get reference for the task list for the logged in user and attach the database listener
    mTaskDatabaseReference=mFirebaseDatabase.getReference().child("users").child(userId);
    attachDatabaseReadListener(context);

}

private void onSignedOutCleanup(Context context) {
    Intent taskIntent = new Intent(context,MainActivity.class);

    // Send the intent to launch a new activity
    context.startActivity(taskIntent);
}

private void detachDatabaseReadListener() {
    if (mChildEventListener != null) {
        mTaskDatabaseReference.removeEventListener(mChildEventListener);
        mChildEventListener = null;
    }
}

Ответы [ 2 ]

0 голосов
/ 06 октября 2018

Итак, в заключение я сохранил текущего вошедшего в систему пользователя, используя SharedPreferences.(Это работает, потому что уведомления относятся к пользователю, поэтому мы можем смело предположить, что последний пользователь, вошедший в систему, является релевантным).

Затем я изменил свое дерево БД Firebase, чтобы позволить мне получать доступ к Задачам, используя текущийвошел в систему идентификатор пользователя.Еще немного кодирования и исправления ошибок, и все готово.

Спасибо за помощь!

0 голосов
/ 05 октября 2018

Если вы хотите отображать эти уведомления еще до того, как пользователь вошел в систему, то очевидно, что они не предназначены для связи с пользователем.Я бы связал их с другим значением, вероятно, идентифицирующим устройство.InstanceIdToken, о котором прокомментировал Джеймс, может быть хорошим решением для этого, поскольку он идентифицирует конкретное приложение на определенном устройстве.

Но также обязательно ознакомьтесь с Firebase Cloud Messaging, который позволяет вам отправлять уведомленияустройство сразу после загрузки.Поскольку сообщения FCM обрабатываются получателем в Службах Google Play, как правило, это более надежный способ доставки таких сообщений, чем попытка загрузить их из удаленной базы данных в свой собственный получатель.

Не случайно: FCMопирается на токены ID экземпляра, чтобы идентифицировать устройство / приложение для доставки сообщения.

...