代码之家  ›  专栏  ›  技术社区  ›  Deepak

当应用程序处于后台或关闭状态时,无法从Firebase消息服务将记录插入SQLite数据库

  •  3
  • Deepak  · 技术社区  · 9 年前

    我正在试用Firebase通知。我能够使用 this 文档消息已收到,我可以从中向通知栏发送通知 MyFirebaseMessagingService 服务级别。即使应用程序处于后台或关闭状态,也会发生这种情况。

    我需要的是收集通知中发送的数据并将其插入SQLite数据库。如果应用程序在前台,我编写的代码可以正常工作,但如果应用程序关闭或在后台,则无法工作。这是我为插页写的。

    DbHelper dbh=new DbHelper(this,"sample.sqlite",null,1);
    SQLiteDatabase sdb=dbh.getWritableDatabase();
    ContentValues cv=new ContentValues();
    cv.put("id","1");
    cv.put("name","testname");
    sdb.insert("test",null,cv);
    sdb.close();
    dbh.close();
    

    感谢您为此提供的任何帮助。提前谢谢。

    <service android:name=".MyFirebaseMessagingService">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>
    
    <service android:name=".MyFirebaseInstanceIDService">
        <intent-filter>
            <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
        </intent-filter>
    </service>
    
    public class MyFirebaseMessagingService extends FirebaseMessagingService
    {
        @Override
        public void onMessageReceived(RemoteMessage remoteMessage) {
            //Displaying data in log
            //It is optional
            Log.i("Tag","inside message" );
            Log.i(StaticInfo.INFO, "From: " + remoteMessage.getFrom());
            Log.i(StaticInfo.INFO, "Notification Message Title  : " + remoteMessage.getNotification().getTitle());
            Log.i(StaticInfo.INFO, "Notification Message Body   : " + remoteMessage.getNotification().getBody());
    
            insertPromotion();
            sendNotification(remoteMessage.getNotification().getBody());
        }
    
        private void sendNotification(String messageBody) 
        {
            Intent intent = new Intent(this, MainActivity.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
                    PendingIntent.FLAG_ONE_SHOT);
    
            Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
            NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                    .setSmallIcon(R.mipmap.ic_launcher)
                    .setContentTitle("Firebase Push Notification")
                    .setContentText(messageBody)
                    .setAutoCancel(true)
                    .setSound(defaultSoundUri)
                    .setContentIntent(pendingIntent);
    
            NotificationManager notificationManager =
                    (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    
            notificationManager.notify(0, notificationBuilder.build());
        }
    
        private void insertPromotion() 
        {
            DbHelper dbh = new DbHelper(this, "sample.sqlite", null, 1);
            SQLiteDatabase sdb = dbh.getWritableDatabase();
            ContentValues cv=new ContentValues();
            cv.put("id","1");
            cv.put("name","testname");
            sdb.insert("test", null, cv);
            sdb.close();
            dbh.close();
    
            Log.i("Tag","db closed");
        }
    
    }
    
    2 回复  |  直到 9 年前
        1
  •  4
  •   Community Mohan Dere    6 年前

    通知将发送到你的应用程序 onMessageReceived 只有当应用程序位于前台时。当应用程序后台运行或未运行时,系统将处理通知并将其显示在系统托盘中。

    这个 Firebase documentation 解释为:

    通知消息 -FCM会代表客户端应用程序自动向最终用户设备显示消息。通知消息具有一组预定义的用户可见密钥。

    数据报文 -客户端应用程序负责处理数据消息。数据消息只有自定义键值对。

    因为您希望代码始终被调用,所以需要发送数据消息。您无法从Firebase控制台发送数据消息。但如果您已经从应用服务器发送消息,则发送数据消息和通知消息的过程在那里是相同的。唯一的区别在于JSON结构,其中数据消息没有 notification 对象从 documentation on data messages

    {
       "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
       "data" : {
         "Nick" : "Mario",
         "body" : "great match!",
         "Room" : "PortugalVSDenmark"
       },
    }
    
        2
  •  0
  •   nkmuturi    9 年前

    要将在onMessgeReceived()上接收的数据保存到SQLite数据库,即使应用程序处于后台(没有活动正在运行),也可以执行以下操作:

    1) 创建一个扩展IntentService的类,例如:

    public class SQLService extends IntentService {
        private final static String MESSAGE_ID = "message_id";
    
        private MySQLiteDbAdapter mySQLiteAdapter;
    
        public SQLService() {
            super("test-service");
        }
    
        @Override
        public void onCreate() {
            super.onCreate();
    
            // initialize SQLite adapter here using getApplicationContext()
            this.mySQLiteAdapter = new MySQLiteDbAdapter(getApplicationContext());
    
        }
    
        @Override
        protected void onHandleIntent(Intent intent) {
    
            // fetch data to save from intent
            Message message = new Message();
            Message.setMessage_id(intent.getStringExtra(MESSAGE_ID));
            ...
            // save 
            this.mySQLiteAdapter.add(message);
    
        }
    }
    

    2) 从onMessageReceived()方法或Firebase服务扩展中的方法启动服务类,例如:

    @Override
        public void onMessageReceived(RemoteMessage remoteMessage) {
    
            if (remoteMessage.getData() != null) {
    
                Intent intent = new Intent(this, SQLService.class);
                // add data to intent
                intent.putExtra(MESSAGE_ID, remoteMessage.getData().get(MESSAGE_ID));
                ...
                // start the service
                startService(intent);
    
            }
        }
    

    3) 在AndroidManifest.xml中注册服务:

    <application
      ...
            <service
                android:name=".SQLService"
                android:exported="false"/>
      ...
    

    有关更深入的说明,请参见 https://guides.codepath.com/android/Starting-Background-Services