Как создать фоновый сервис Firebase в Android? - PullRequest
0 голосов
/ 08 октября 2019

Я новичок в Android. Я хотел бы создать фоновый сервис в Android, который прослушивает новый документ, созданный в Firestore. У меня весь код готов, но застрял с запуском сервиса снова и снова.

  • Подскажите, пожалуйста, что мне нужно сделать, чтобы запустить сервис только один раз. Всякий раз, когда я открываю приложение, оно печатает >> слушатель, прикрепленный в консоли. Я хочу, чтобы он выполнялся только один раз и работал в фоновом режиме.

  • Что произойдет, если я обновлю приложение в Play store и перезапустит ли сервис новый код, обновленный в приложении?

Пример кода, за которым я следовал: https://gist.github.com/vikrum/6170193

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.demo">

    <uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
    <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
    <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_CONTACTS" />
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".SignUp">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
       <!-- Other activities -->

        <!-- authentication service -->

        <service android:name=".service.firestore.listener.FirestoreActivityListener"
            android:exported="false"
            android:process=":remote">
        </service>
    </application>
</manifest>

FirestoreActivityListener.java

package com.demo.service.firestore.listener;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;

import com.google.firebase.FirebaseApp;
import com.google.firebase.firestore.DocumentChange;
import com.google.firebase.firestore.EventListener;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.FirebaseFirestoreException;
import com.google.firebase.firestore.FirebaseFirestoreSettings;
import com.google.firebase.firestore.QuerySnapshot;

import javax.annotation.Nullable;

import static com.google.firebase.firestore.DocumentChange.Type.ADDED;

/**
 * @author vicky.thakor
 * @since 2019-02-06
 */
public class FirestoreActivityListener extends Service {

    private static final String COLLECTION = "users/%s/activities";
    private FirebaseFirestore firestore;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        FirebaseApp.initializeApp(this);
        this.firestore = FirebaseFirestore.getInstance();
        FirebaseFirestoreSettings settings = new FirebaseFirestoreSettings.Builder()
                .setTimestampsInSnapshotsEnabled(true)
                .build();
        firestore.setFirestoreSettings(settings);
        activitiesListener();
    }

    public void activitiesListener(){
        System.err.println(">> listener attached");
        firestore.collection(String.format(COLLECTION, "xxxxxxxxx"))
                .addSnapshotListener(new EventListener<QuerySnapshot>() {
                    @Override
                    public void onEvent(@Nullable QuerySnapshot querySnapshot, @Nullable FirebaseFirestoreException e) {
                        for (DocumentChange dc : querySnapshot.getDocumentChanges()) {
                            switch (dc.getType()) {
                                case ADDED:
                                    System.err.println(">> " + dc.getDocument().toString());
                                    break;
                            }
                        }
                    }
                });
    }
}

SignUp.java

package com.demo;

import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.Button;
import android.widget.EditText;

import com.google.firebase.FirebaseApp;
import com.google.firebase.FirebaseException;
import com.google.firebase.FirebaseTooManyRequestsException;
import com.google.firebase.auth.FirebaseAuthInvalidCredentialsException;
import com.google.firebase.auth.PhoneAuthCredential;
import com.google.firebase.auth.PhoneAuthProvider;
import com.demo.home.Home;
import com.demo.model.ParcelableUser;
import com.demo.repository.SharedPreferencesRepository;
import com.demo.repository.impl.SharedPreferencesRepositoryImpl;
import com.demo.service.firestore.listener.FirestoreActivityListener;
import com.demo.util.AlertUtil;
import com.demo.util.IntentConstants;
import com.demo.util.StringUtil;

import java.util.concurrent.TimeUnit;

public class SignUp extends AppCompatActivity {

    private SharedPreferencesRepository sharedPreferencesRepository;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        /* initialization */
        sharedPreferencesRepository = new SharedPreferencesRepositoryImpl(this);
        startService(new Intent(this, FirestoreActivityListener.class));
        verifyRegisteredUser();

        setContentView(R.layout.signup);
        registerNewUser();
    }

    private void verifyRegisteredUser() {
        .....
    }

    private void registerNewUser() {
        .....
    }
}

1 Ответ

3 голосов
/ 08 октября 2019

Я бы хотел создать в Android фоновую службу, которая будет прослушивать новый документ, созданный в Firestore.

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

Согласно официальной документации относительно Службы Android , если вы хотите получить максимальную выгоду от работающей службы:

Служба переднего плана выполняет некоторую операцию, которая заметна для пользователя. Например, аудио приложение будет использовать сервис переднего плана для воспроизведения звуковой дорожки. Службы Foreground должны отображать Уведомление . Службы Foreground продолжают работать, даже когда пользователь не взаимодействует с приложением.

Итак, другими словами, вам нужно будет предоставить значок для уведомления, чтобы пользователь был проинформирован о том, что приложениепотребляет ресурсы.

Согласно вашему комментарию:

Нет, я хочу прослушать новые документы, созданные в Firestore.

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

Это способ, которым вы имеете дело с Firestore, когда хотите прослушать некоторые документы в фоновом режиме. но, пожалуйста, также рассмотрите возможность использования Облачных функций для Firebase :

Облачные функции для Firebase позволяют автоматически запускать внутренний код в ответ на события, инициируемые функциями Firebase и запросами HTTPS. Ваш код хранится в облаке Google и работает в управляемой среде. Нет необходимости управлять и масштабировать свои собственные серверы.

Редактировать:

Как на самом деле работают облачные функции?

Как и в случае с клиентом, Cloud Functions также позволяет вам присоединить слушателя к одному документу или даже к запросу. Таким образом, облачная функция может быть запущена, когда в вашей базе данных происходит что-то особенное, например, когда некоторые документы записываются в коллекцию Firestore. Как только функция сработает, вы можете предпринять некоторые действия. Как отметил Фрэнк ван Пуффелен в своем комментарии, вы можете отправить уведомление, например. Для Android см. Ниже простой пример:

Может быть, это не то, что вы хотите, чтобы отправитьуведомление, но это простой пример, и я думаю, что вы сможете понять идею.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...