如何在Android中创建Firebase后台服务? [英] How to create firebase background service in Android?

查看:40
本文介绍了如何在Android中创建Firebase后台服务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Android的新手.我想在android中创建后台服务,以侦听Firestore中创建的新文档.我已经准备好所有代码,但始终无法启动服务.

I'm newbie to Android. I'd like to create background service in android that listen for new Document created in Firestore. I've all code ready but stuck with service starting again and again.

  • 能否请您告诉我该怎么做才能启动服务一次.每当我打开应用程序时,它都会在控制台中显示>>附加的监听器.我希望它只执行一次并使其在后台运行.

  • Can you please tell what should I do to start service only once. Whenever I open app it prints >> listener attached in console. I want it to execute only once and keep it running in background.

如果我在Play商店中更新了应用程序,它将使用应用程序中更新的新代码重新启动服务,会发生什么?

What happens if I update application on Play store and will it restart service with new code updated in application?

我遵循的示例代码: 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() {
        .....
    }
}

推荐答案

我想在android中创建后台服务,以侦听Firestore中创建的新文档.

I'd like to create background service in android that listen for new Document created in Firestore.

您确实可以在Android服务中执行此操作,但是请记住,服务仅代表您可以告诉OS您必须完成一些后台工作且实际上并不需要附加视图(活动).

It's true that you can do that in an Android Service but please rememeber that a service represents only a way in which you can tell the OS that you have some background work that has to be done and that doesn't really requiere an attached view (activity).

根据有关 Android服务的官方文档,如果您想从中受益尽可能运行的服务:

According to the official documentatation regarding Android services, if you want to benefit from a running service as much as possible:

前台服务执行一些用户注意到的操作.例如,音频应用程序将使用前台服务来播放音轨.前台服务必须显示通知.即使用户未与应用程序进行交互,前景服务也将继续运行.

A foreground service performs some operation that is noticeable to the user. For example, an audio app would use a foreground service to play an audio track. Foreground services must display a Notification. Foreground services continue running even when the user isn't interacting with the app.

换句话说,您需要为通知提供一个图标,以便通知用户该应用正在消耗资源.

So with other words, you'll need to provide an icon for the notification, so the user is informed that the app is consuming resources.

根据您的评论:

不是,我想听在Firestore中创建的新文档.

Nope I want to listen for new documents created in Firestore.

是的,您可以在数据库中甚至某个查询中附加一个侦听器,并且该侦听器会随着结果的更改而更新.但是请记住,您将必须对所获得的每个更新都进行读操作,这基本上意味着用户还将承担带宽成本以及电池耗电成本.因此,我总是建议根据生活情况移除听众活动的骑自行车者.

Yes, you can have a listener attached to some document in your database or even to a query, and it will update as the results change. But remeber that you will have to pay a read operation for each of the updates that you get, basically meaning that the user will also have the cost for the bandwidth, and the cost of their battery drain. So I always recommend remove the listeners according to the life-cycler of the activity.

当您想在后台听一些文档时,这是您与Firestore进行交易的一种方式,但也请考虑使用 Firebase的云功能:

That's a way in which you you deal with Firestore when you want to listen to some documents in a background but please also consider using Cloud Functions for Firebase:

用于Firebase的云功能使您可以自动运行后端代码,以响应由Firebase功能和HTTPS请求触发的事件.您的代码存储在Google的云中,并在托管环境中运行.无需管理和扩展自己的服务器.

Cloud Functions for Firebase let you automatically run backend code in response to events triggered by Firebase features and HTTPS requests. Your code is stored in Google's cloud and runs in a managed environment. There's no need to manage and scale your own servers.

云功能实际上如何工作?

How do Cloud Functions actually work?

与客户端一样,Cloud Functions还允许您将侦听器附加到单个文档甚至查询.因此,当数据库中发生某些特殊情况时(例如,将某些文档写入Firestore集合中时),可以触发Cloud Function.触发功能后,您可以采取一些措施.正如弗兰克·范·普菲伦(Frank van Puffelen)在其评论中提到的,您可以发送例如通知.对于Android,请参见下面的简单示例:

As in the case of the client, Cloud Functions also allows you to attach a listener to a single document or even to a query. So a Cloud Function can be triggered when something special in your database happens, for instance when some documents gets written into a Firestore collection. Once the function is triggered, you can take some action. As Frank van Puffelen mentioned in his comment, you can send a notification for example. For Android, please see below a straightforward example:

发送通知可能不是您想要的,但这只是一个简单的示例,我认为您将能够理解.

Maybe this is not what you want, to send a notification but it's a simple example and I think you'll be able to get the idea.

这篇关于如何在Android中创建Firebase后台服务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆