We use GCM in our apps to receive push notifications which is little tricky to implement. You can do the same using the free push service provided by Parse.com also. Compared to GCM, using parse is very simple. You can implement and test the push notifications in just 2 mins by following steps mentioned here. But this tutorial is aimed to customize the parse push service as much as possible.

In this tutorial we’ll learn how to customize the default push broadcast receiver, handling the json push messages, using the parse dashboard to send messages, customizing the push icons and lot more.

Android Push Notifications using Parse.com

We’ll also build a simple app with a login and home screen. Login screen prompts users to enter their email address which will be used to send personalized messages individually. Home screen is to show the push messages in a list view. So let’s get started with basic parse setup.

1. Parse Applciation ID, Client Key & parse-x.x.x.jar

To integrate parse in your app, you need Application ID, Client Key and parse jar library. Follow the below steps to get your app keys.

1. Sign Up by entering the details required.

2. Create a new parse app.

3. Once the app is created, go to Settings of the app and grab the Application ID and Client Key.

4. Download latest version of parse-1.9.2.jar. This library contains necessary functions to interact with parse API.

android parse application id and client key

Check out the below video demonstrating the parse setup.

2. Push Notification JSON

While we send push notification, we use json to interact with the android app. Below is the structure of the json which we use in this tutorial. This json structured varies from app to app depending upon the requirement.

is_background – flag decides whether to show the notification or not. This flag will be useful to do any background jobs on receiving push notification. When this flag is set to true, notification won’t to be shown to user.

{
    "data": {
        "message": "Hello! Welcome to parse notifications.",
        "title": "AndroidHive"
    },
    "is_background": false
}

3. Creating Android Project

1. In Android Studio, create a new project by navigating to File ⇒ New Project and fill all the required details.

2. Follow my material design tutorial to convert this app into material app. (But this step is optional)

3. In project’s app ⇒ libs folder, paste the Parse-1.9.2.jar file. You can find this jar file in the downloaded parse library that we have downloaded in above step.

4. Open build.gradle located under app folder and add below dependencies.

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile "com.android.support:appcompat-v7:22.1.1"

    compile 'com.parse.bolts:bolts-android:1.+'
    compile fileTree(dir: 'libs', include: 'Parse-*.jar')
}

5. Open strings.xml and add below string values.

<resources>
    <string name="app_name">Parse Push</string>

    <string name="action_settings">Settings</string>
    <string name="title_activity_login">LoginActivity</string>
    <string name="action_logout">Logout</string>
</resources>

6. Open colors.xml and add below color values. If you did’t find colors.xml, create a new file with the name.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#218eed</color>
    <color name="colorPrimaryDark">#218eed</color>
    <color name="textColorPrimary">#FFFFFF</color>
    <color name="windowBackground">#FFFFFF</color>
    <color name="navigationBarColor">#000000</color>
    <color name="colorAccent">#8e8e8e</color>
</resources>

7. Under res ⇒ layout, create an xml named toolbar.xml. This adds an action bar to our app.

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res-auto"
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="?attr/colorPrimary"
    android:minHeight="?attr/actionBarSize"
    local:popupTheme="@style/ThemeOverlay.AppCompat.Light"
    local:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />

8. Now quickly create 5 packages named activity, app, helper, model and receiver under your project. These packages will helps to you keep your project organized.

android-parse-push-notifications-project-structure

9. Under app package, create a class named AppConfig.java and add below configuration. Replace parse keys with your Parse Application Key and Client Id.

The channel name ‘AndroidHive‘ is the channel to which every user will be subscribed to. So that you can send a generic message all the users subscribed to that channel.

package info.androidhive.parsenotifications.app;

/**
 * Created by Ravi on 15/05/15.
 */
public class AppConfig {
    public static final String PARSE_CHANNEL = "AndroidHive";
    public static final String PARSE_APPLICATION_ID = "ZUSZNPfsop5GnsjZPc4ajRittIUj3ilvC8dPLbC0";
    public static final String PARSE_CLIENT_KEY = "3kCVPLxA09hFUCkWB9Hc5isS6lOb6iYtG2gIcf1k";
    public static final int NOTIFICATION_ID = 100;
}

10. Now we’ll quickly create three helper classes required for this project. Create a class named ParseUtils.java under helper package. This class contains utility methods to interact with parse API like initializing the parse, subscribing using email to send individual notifications.

package info.androidhive.parsenotifications.helper;

import android.app.Activity;
import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import com.parse.Parse;
import com.parse.ParseException;
import com.parse.ParseInstallation;
import com.parse.ParsePush;
import com.parse.SaveCallback;

import info.androidhive.parsenotifications.app.AppConfig;

/**
 * Created by Ravi on 01/06/15.
 */
public class ParseUtils {

    private static String TAG = ParseUtils.class.getSimpleName();

    public static void verifyParseConfiguration(Context context) {
        if (TextUtils.isEmpty(AppConfig.PARSE_APPLICATION_ID) || TextUtils.isEmpty(AppConfig.PARSE_CLIENT_KEY)) {
            Toast.makeText(context, "Please configure your Parse Application ID and Client Key in AppConfig.java", Toast.LENGTH_LONG).show();
            ((Activity) context).finish();
        }
    }

    public static void registerParse(Context context) {
        // initializing parse library
        Parse.initialize(context, AppConfig.PARSE_APPLICATION_ID, AppConfig.PARSE_CLIENT_KEY);
        ParseInstallation.getCurrentInstallation().saveInBackground();

        ParsePush.subscribeInBackground(AppConfig.PARSE_CHANNEL, new SaveCallback() {
            @Override
            public void done(ParseException e) {
                Log.e(TAG, "Successfully subscribed to Parse!");
            }
        });
    }

    public static void subscribeWithEmail(String email) {
        ParseInstallation installation = ParseInstallation.getCurrentInstallation();

        installation.put("email", email);

        installation.saveInBackground();
    }
}

11. Create a class named NotificationUtils.java under helper package. This class contains below useful methods to handle the notifications.

> showNotificationMessage() – shows the notification in notification area by setting appropriate title, message, icon and intent.

> isAppIsInBackground() – checks whether your app is in background or foreground.

package info.androidhive.parsenotifications.helper;

import android.app.ActivityManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.media.RingtoneManager;
import android.os.Build;
import android.support.v4.app.NotificationCompat;
import android.text.TextUtils;
import android.widget.Toast;

import java.util.List;

import info.androidhive.parsenotifications.R;
import info.androidhive.parsenotifications.activity.MainActivity;
import info.androidhive.parsenotifications.app.AppConfig;

/**
 * Created by Ravi on 01/06/15.
 */
public class NotificationUtils {

    private String TAG = NotificationUtils.class.getSimpleName();

    private Context mContext;

    public NotificationUtils() {
    }

    public NotificationUtils(Context mContext) {
        this.mContext = mContext;
    }

    public void showNotificationMessage(String title, String message, Intent intent) {

        // Check for empty push message
        if (TextUtils.isEmpty(message))
            return;

        if (isAppIsInBackground(mContext)) {
            // notification icon
            int icon = R.mipmap.ic_launcher;

            int mNotificationId = AppConfig.NOTIFICATION_ID;

            PendingIntent resultPendingIntent =
                    PendingIntent.getActivity(
                            mContext,
                            0,
                            intent,
                            PendingIntent.FLAG_CANCEL_CURRENT
                    );

            NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle();

            NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
                    mContext);
            Notification notification = mBuilder.setSmallIcon(icon).setTicker(title).setWhen(0)
                    .setAutoCancel(true)
                    .setContentTitle(title)
                    .setStyle(inboxStyle)
                    .setContentIntent(resultPendingIntent)
                    .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
                    .setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), icon))
                    .setContentText(message)
                    .build();

            NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
            notificationManager.notify(mNotificationId, notification);
        } else {
            intent.putExtra("title", title);
            intent.putExtra("message", message);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
            mContext.startActivity(intent);
        }
    }

    /**
     * Method checks if the app is in background or not
     *
     * @param context
     * @return
     */
    public static boolean isAppIsInBackground(Context context) {
        boolean isInBackground = true;
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT_WATCH) {
            List<ActivityManager.RunningAppProcessInfo> runningProcesses = am.getRunningAppProcesses();
            for (ActivityManager.RunningAppProcessInfo processInfo : runningProcesses) {
                if (processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
                    for (String activeProcess : processInfo.pkgList) {
                        if (activeProcess.equals(context.getPackageName())) {
                            isInBackground = false;
                        }
                    }
                }
            }
        } else {
            List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
            ComponentName componentInfo = taskInfo.get(0).topActivity;
            if (componentInfo.getPackageName().equals(context.getPackageName())) {
                isInBackground = false;
            }
        }

        return isInBackground;
    }
}

12. Create another class named PrefManager.java under helper package. This class handles the user’s session with the help of shared preferences.

package info.androidhive.parsenotifications.helper;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;

/**
 * Created by Ravi on 01/06/15.
 */
public class PrefManager {
    // Shared Preferences
    SharedPreferences pref;

    // Editor for Shared preferences
    Editor editor;

    // Context
    Context _context;

    // Shared pref mode
    int PRIVATE_MODE = 0;

    // Shared pref file name
    private static final String PREF_NAME = "AndroidHive";

    // All Shared Preferences Keys
    private static final String IS_LOGIN = "IsLoggedIn";

    // Email address
    private static final String KEY_EMAIL = "email";

    // Constructor
    public PrefManager(Context context) {
        this._context = context;
        pref = _context.getSharedPreferences(PREF_NAME, PRIVATE_MODE);
        editor = pref.edit();
    }

    /**
     * Create login session
     */
    public void createLoginSession(String email) {
        // Storing login value as TRUE
        editor.putBoolean(IS_LOGIN, true);

        // Storing email in pref
        editor.putString(KEY_EMAIL, email);

        // commit changes
        editor.commit();
    }

    public String getEmail() {
        return pref.getString(KEY_EMAIL, null);
    }

    public boolean isLoggedIn() {
        return pref.getBoolean(IS_LOGIN, false);
    }

    public void logout() {
        editor.clear();
        editor.commit();
    }
}

13. Now under app package, create another class named MyApplication.java and add below code. This is an Application class which will be executed on app launch. So we initialize the parse by calling ParseUtils.registerParse() method which initializes the parse and subscribe the user to AndroidHive channel.

package info.androidhive.parsenotifications.app;


import android.app.Application;

import info.androidhive.parsenotifications.helper.ParseUtils;

public class MyApplication extends Application {

    private static MyApplication mInstance;

    @Override
    public void onCreate() {
        super.onCreate();
        mInstance = this;

        // register with parse
        ParseUtils.registerParse(this);
    }


    public static synchronized MyApplication getInstance() {
        return mInstance;
    }
}

3.1 Creating Custom Parse Push Receiver

Parse comes with a default broadcast push receiver, but the options are limited. If you want to fully utilize the parse notifications, the best option is create a custom broad cast receiver.

14. Under receiver package, create a class named CustomPushReceiver.java which extends ParsePushBroadcastReceiver.

onPushReceive() – method will be called whenever push message is received. In this message the json message will be parsed and shown to user.

package info.androidhive.parsenotifications.receiver;

import android.content.Context;
import android.content.Intent;
import android.util.Log;

import com.parse.ParsePushBroadcastReceiver;

import org.json.JSONException;
import org.json.JSONObject;

import info.androidhive.parsenotifications.activity.MainActivity;
import info.androidhive.parsenotifications.helper.NotificationUtils;

/**
 * Created by Ravi on 01/06/15.
 */
public class CustomPushReceiver extends ParsePushBroadcastReceiver {
    private final String TAG = CustomPushReceiver.class.getSimpleName();

    private NotificationUtils notificationUtils;

    private Intent parseIntent;

    public CustomPushReceiver() {
        super();
    }

    @Override
    protected void onPushReceive(Context context, Intent intent) {
        super.onPushReceive(context, intent);

        if (intent == null)
            return;

        try {
            JSONObject json = new JSONObject(intent.getExtras().getString("com.parse.Data"));

            Log.e(TAG, "Push received: " + json);

            parseIntent = intent;

            parsePushJson(context, json);

        } catch (JSONException e) {
            Log.e(TAG, "Push message json exception: " + e.getMessage());
        }
    }

    @Override
    protected void onPushDismiss(Context context, Intent intent) {
        super.onPushDismiss(context, intent);
    }

    @Override
    protected void onPushOpen(Context context, Intent intent) {
        super.onPushOpen(context, intent);
    }

    /**
     * Parses the push notification json
     *
     * @param context
     * @param json
     */
    private void parsePushJson(Context context, JSONObject json) {
        try {
            boolean isBackground = json.getBoolean("is_background");
            JSONObject data = json.getJSONObject("data");
            String title = data.getString("title");
            String message = data.getString("message");

            if (!isBackground) {
                Intent resultIntent = new Intent(context, MainActivity.class);
                showNotificationMessage(context, title, message, resultIntent);
            }

        } catch (JSONException e) {
            Log.e(TAG, "Push message json exception: " + e.getMessage());
        }
    }


    /**
     * Shows the notification message in the notification bar
     * If the app is in background, launches the app
     *
     * @param context
     * @param title
     * @param message
     * @param intent
     */
    private void showNotificationMessage(Context context, String title, String message, Intent intent) {

        notificationUtils = new NotificationUtils(context);

        intent.putExtras(parseIntent.getExtras());

        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);

        notificationUtils.showNotificationMessage(title, message, intent);
    }
}

15. Now we have all the helper classes required. Open AndroidManifest.xml and do the below changes.

> Add MyApplication to your <application> tag

> Make LoginActivity as launcher activity. We’ll create this activity shortly.

> Replace info.androidhive.parsenotifications with your project’s package name.

> Add the custom receiver class CustomPushReceiver using <receiver> tag.

> Add the necessary permissions mentioned.

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

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

    <!--
      IMPORTANT: Change "info.androidhive.parsenotifications.permission.C2D_MESSAGE" in the lines below
      to match your app's package name + ".permission.C2D_MESSAGE".
    -->
    <permission
        android:name="info.androidhive.parsenotifications.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />

    <uses-permission android:name="info.androidhive.parsenotifications.permission.C2D_MESSAGE" />

    <application
        android:name=".app.MyApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/MyMaterialTheme">
        <activity
            android:name=".activity.LoginActivity"
            android:label="@string/app_name"
            android:windowSoftInputMode="stateHidden|adjustResize">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".activity.MainActivity"
            android:label="@string/app_name" />

        <!-- Added for Parse push notifications -->

        <service android:name="com.parse.PushService" />

        <receiver
            android:name=".receiver.CustomPushReceiver"
            android:exported="false">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.intent.action.USER_PRESENT" />
                <action android:name="com.parse.push.intent.RECEIVE" />
                <action android:name="com.parse.push.intent.DELETE" />
                <action android:name="com.parse.push.intent.OPEN" />
            </intent-filter>
        </receiver>
        <receiver
            android:name="com.parse.GcmBroadcastReceiver"
            android:permission="com.google.android.c2dm.permission.SEND">
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                <action android:name="com.google.android.c2dm.intent.REGISTRATION" />

                <!-- IMPORTANT: Change "info.androidhive.parsenotifications" to match your app's package name. -->
                <category android:name="info.androidhive.parsenotifications" />
            </intent-filter>
        </receiver>

        <!-- /Added for Parse push notifications -->
    </application>

</manifest>

3.1 Creating Login Activity

Now we’ll add the login screen to our app. This will be the launcher activity which prompts user to enter the email to login. Using this email address, we’ll subscribe the user to parse channel email.

16. Create an xml layout named activity_login.xml under res ⇒ layout folder.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff"
    tools:context="info.androidhive.parsenotifications.activity.LoginActivity">

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:gravity="center"
        android:orientation="vertical"
        android:paddingBottom="10dp"
        android:paddingTop="10dp">

        <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:fontFamily="sans-serif-light"
            android:gravity="center_horizontal"
            android:text="Parse Notifications"
            android:textColor="#218eed"
            android:textSize="24dp" />

        <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="20dp"
            android:fontFamily="sans-serif-light"
            android:gravity="center_horizontal"
            android:paddingLeft="20dp"
            android:paddingRight="20dp"
            android:text="Enter your email address to subscribe to parse channel!"
            android:textColor="#9d9d9d"
            android:textSize="16dp" />

        <EditText
            android:id="@+id/email"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="40dp"
            android:layout_marginRight="40dp"
            android:background="@android:color/white"
            android:hint="Your email address"
            android:gravity="center_horizontal"
            android:inputType="textEmailAddress"
            android:padding="10dp"
            android:textColor="#444444"
            android:textColorHint="#888888"
            android:textSize="18dp" />

        <View
            android:layout_width="fill_parent"
            android:layout_height="1dp"
            android:layout_marginLeft="40dp"
            android:layout_marginRight="40dp"
            android:background="#dedede"/>

        <Button
            android:id="@+id/btnLogin"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="40dp"
            android:layout_marginRight="40dp"
            android:layout_marginTop="20dp"
            android:background="#218eed"
            android:text="Login"
            android:textColor="@android:color/white" />
    </LinearLayout>


</RelativeLayout>

17. Under activity package, create a new activity named LoginActivity.java and add below code. This activity get the email address and stores it in shared preferences.

package info.androidhive.parsenotifications.activity;

import android.content.Intent;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import info.androidhive.parsenotifications.R;
import info.androidhive.parsenotifications.app.AppConfig;
import info.androidhive.parsenotifications.helper.ParseUtils;
import info.androidhive.parsenotifications.helper.PrefManager;

public class LoginActivity extends ActionBarActivity implements View.OnClickListener {

    private EditText inputEmail;
    private Button btnLogin;
    private PrefManager pref;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Verifying parse configuration. This is method is for developers only.
        ParseUtils.verifyParseConfiguration(this);

        pref = new PrefManager(getApplicationContext());
        if (pref.isLoggedIn()) {
            Intent intent = new Intent(LoginActivity.this, MainActivity.class);
            startActivity(intent);

            finish();
        }

        setContentView(R.layout.activity_login);

        inputEmail = (EditText) findViewById(R.id.email);
        btnLogin = (Button) findViewById(R.id.btnLogin);

        btnLogin.setOnClickListener(this);
    }


    private void login() {
        String email = inputEmail.getText().toString();

        if (isValidEmail(email)) {

            pref.createLoginSession(email);

            Intent intent = new Intent(LoginActivity.this, MainActivity.class);
            startActivity(intent);

            finish();
        } else {
            Toast.makeText(getApplicationContext(), "Please enter valid email address!", Toast.LENGTH_LONG).show();
        }
    }

    public final static boolean isValidEmail(CharSequence target) {
        return !TextUtils.isEmpty(target) && android.util.Patterns.EMAIL_ADDRESS.matcher(target).matches();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btnLogin:
                login();
                break;
            default:
        }
    }
}

android-push-notifications-email-subscription

3.2 Showing the Push Messages in List View

18. Under model package, create a class named Message.java. This class is used to pass the message objects to list adapter.

package info.androidhive.parsenotifications.model;

/**
 * Created by Ravi on 01/06/15.
 */
public class Message {
    private String message;
    private long timestamp;

    public Message() {
    }

    public Message(String message, long timestamp) {
        this.message = message;
        this.timestamp = timestamp;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public long getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(long timestamp) {
        this.timestamp = timestamp;
    }
}

19. Create an xml layout named list_row.xml. This layout renders the single list item row.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/message"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:paddingBottom="5dp"
        android:paddingLeft="10dp"
        android:paddingRight="10dp"
        android:paddingTop="10dp"
        android:textSize="16dp" />

    <TextView
        android:id="@+id/timestamp"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:paddingBottom="15dp"
        android:paddingLeft="10dp"
        android:paddingRight="10dp"
        android:textColor="#666666" />

</LinearLayout>

20. Open layout file of main activity (activity_main.xml) and add a ListView.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <include
            android:id="@+id/toolbar"
            layout="@layout/toolbar" />
    </LinearLayout>

    <ListView
        android:id="@+id/list_view"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"></ListView>

</LinearLayout>

21. Finally open your main activity class MainActivity.java and do the below changes. Here onNewIntent() method will be called whenever a new push message is received. We’ll add the new message to list data source and refresh the list view.

package info.androidhive.parsenotifications.activity;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.text.format.DateUtils;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

import info.androidhive.parsenotifications.R;
import info.androidhive.parsenotifications.helper.ParseUtils;
import info.androidhive.parsenotifications.helper.PrefManager;
import info.androidhive.parsenotifications.model.Message;


public class MainActivity extends AppCompatActivity {

    private static String TAG = MainActivity.class.getSimpleName();

    private Toolbar mToolbar;
    private ListView listView;
    private List<Message> listMessages = new ArrayList<>();
    private MessageAdapter adapter;
    private PrefManager pref;

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

        listView = (ListView) findViewById(R.id.list_view);
        mToolbar = (Toolbar) findViewById(R.id.toolbar);

        setSupportActionBar(mToolbar);
        getSupportActionBar().setDisplayShowHomeEnabled(true);

        adapter = new MessageAdapter(this);
        pref = new PrefManager(getApplicationContext());

        listView.setAdapter(adapter);

        Intent intent = getIntent();

        String email = intent.getStringExtra("email");

        if (email != null) {
            ParseUtils.subscribeWithEmail(pref.getEmail());
        }
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        String message = intent.getStringExtra("message");

        Message m = new Message(message, System.currentTimeMillis());
        listMessages.add(0, m);
        adapter.notifyDataSetChanged();
    }

    private class MessageAdapter extends BaseAdapter {

        LayoutInflater inflater;

        public MessageAdapter(Activity activity) {
            inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        }

        @Override
        public int getCount() {
            return listMessages.size();
        }

        @Override
        public Object getItem(int position) {
            return listMessages.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View view = convertView;
            if (view == null) {
                view = inflater.inflate(R.layout.list_row, null);
            }

            TextView txtMessage = (TextView) view.findViewById(R.id.message);
            TextView txtTimestamp = (TextView) view.findViewById(R.id.timestamp);

            Message message = listMessages.get(position);
            txtMessage.setText(message.getMessage());

            CharSequence ago = DateUtils.getRelativeTimeSpanString(message.getTimestamp(), System.currentTimeMillis(),
                    0L, DateUtils.FORMAT_ABBREV_ALL);

            txtTimestamp.setText(String.valueOf(ago));

            return view;
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_logout) {
            pref.logout();
            Intent intent = new Intent(MainActivity.this, LoginActivity.class);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
            startActivity(intent);
            finish();
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

This completes the android part. Now we’ll learn how to use the parse dashboard to send push messages.

android-push-notifications-list-view

4. Sending Messages using Parse Dashboard

Parse provides the push dashboard to send messages to all your app users. Login to parse, select the app and click on + Send a push. You can find necessary filters to send push notifications like by platform, channel etc., Checkout the demo video above demonstrating sending the push messages to all users, by a channel or by email.

5. Sending Messages using Parse REST API

Parse also provides a REST API for various languages to send the messages from your server directly instead of using the parse dashboard. This REST API is very useful when you want to automate the push messages when user is interacting with the android app.

Go through the REST API guide to integrate the API with the language you choose.

Subscribe
Notify of
guest
193 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Ahmed Turk
Ahmed Turk
5 years ago

Awesome , thank you for this , but i want to know if i can save the messages on the app when it come , i don’t want the app to delete any of the notifications , how to save it to check it later & so on.. please answer & thank u

Ahmed Turk
Ahmed Turk
5 years ago

please help saving the state of the notifications inside the app , i really need it

Ravi Tamada
5 years ago
Reply to  Ahmed Turk
Ahmed Turk
Ahmed Turk
5 years ago
Reply to  Ravi Tamada

thank you & sorry for that but i am still learning can you help by creating simple project implementing the SQLite inside the parse app , sorry again & i appreciate your help , i learned alot from your examples , you are a good developer keep it up..

Andrew
Andrew
5 years ago
Reply to  Ahmed Turk

My solution is that I send it from my server via curl and it is stored in mysql. If anyone need to see the history of the notifications it is simple loaded in a listview from json.

Ahmed Turk
Ahmed Turk
5 years ago
Reply to  Andrew

its kinda simple for you guys but i am still learning so its complicated to me 😀

Ravi Tamada
5 years ago
Reply to  Ahmed Turk

Nothing is complicated, all you have to do it practise 🙂

Trey Rosius
Trey Rosius
5 years ago
Reply to  Ravi Tamada

well said Sir….Well Said!

Sahitya Kumar Suman
Sahitya Kumar Suman
5 years ago

Why my push is only submitted to my emulator …..do i need to upload my application on playstore to provide push notification to my other user …….. very urgent please rply

Ravi Tamada
5 years ago

Could you explain your problem clearly?

Sahitya Kumar Suman
Sahitya Kumar Suman
5 years ago
Reply to  Ravi Tamada

I have done all things clearly but the thing is that push notification is working fine with only emulator on my laptop where ever i try to send the notification to any real device it doesn’t show anything on the device.

Ravi Tamada
5 years ago

Which real device you are trying on. Check the logcat for any exceptions. If you are not finding any errors in logcat, check the device info and parse dashboard. Device ID shouldn’t be null.

Ahmed Turk
Ahmed Turk
5 years ago

i faced that at first , so i deleted the app from the parse website & i created a new one and registered with a new email on the app & as ravi said make sure that the device ID not null , it should be filled by the device ID to work…

Sahitya Kumar Suman
Sahitya Kumar Suman
5 years ago
Reply to  Ahmed Turk

Its working now fine ……. thanx @Ravi @Ahmed …………

Sahitya Kumar Suman
Sahitya Kumar Suman
5 years ago
Reply to  Ravi Tamada

How could i solve this problem. i have searched a lot on stacoverflow and even went deep in documentation of parse.com but didnt find any solution for it. Do i need to register my app on playstore to work on real device ……. i have full internet connection on my device and also GCM is installed on it ….. what could be the the possible reason for it …. help me

Renitto Jose
Renitto Jose
5 years ago

Did this before . nice tutorial anyways. 🙂

Sahitya Kumar Suman
Sahitya Kumar Suman
5 years ago
Reply to  Renitto Jose

A long ago .. but now i am facing some prblm if you can plz help me ………..I have done all things clearly but the thing is that push notification
is working fine with only emulator on my laptop where ever i try to send
the notification to any real device it doesn’t show anything on the
device.

Renitto Jose
Renitto Jose
5 years ago

@sahitya have you checked on parse.com push interface ?? it will show the details of push sent, device , json n all .

Rakhi Dhavale
5 years ago

Thanks ! Will try this out !

Yura Ozhyrko
Yura Ozhyrko
5 years ago

Do the same by using SignalR library and own server.

Krupen Ghetiya
Krupen Ghetiya
5 years ago

Very Nice Tutorial, All your tutorials are amazing.
Also there is another website http://apphq.shephertz.com/ with quite similar functionality and I found that quite easy to implement. Will try this one too now.

karampal
karampal
5 years ago

Thanks, Ravi finally u come on parse.com, I waiting when u give tutorials about using recyclerview and card view with parse.com and thanks again for this nice tutorial…..

Test User
Test User
5 years ago

Thanks, good explanation.

Ahmed Turk
Ahmed Turk
5 years ago

I used the SQLite to save the messages as you said & it worked but what about when i receive the message in the notification i click on it open the app without saving the new message that showing the old ones that i received when the app was on the front ! so what i can do ! HELP PLEASE

boyapati Subrahmanyam
boyapati Subrahmanyam
5 years ago
Reply to  Ahmed Turk

once you click on notification store the arrived message in sqlite and load list.

Gon Her
Gon Her
5 years ago

Excellent tutorial. thank you very much

sampath
sampath
5 years ago

getting error at this ParsePush.subscribeInBackground any help ravi…

Ahmed Turk
Ahmed Turk
5 years ago
Reply to  sampath

you used the project in eclipse ?

Ahmed Turk
Ahmed Turk
5 years ago
Reply to  Ahmed Turk

if in eclipse download the android parse sdk from this page https://www.parse.com/docs/downloads then extract the zip file & pull bolts-android-1.2.0.jar into your libs folder in eclipse & it should work

Gergis Fawzy Caesar
Gergis Fawzy Caesar
5 years ago

Error:Execution failed for task ‘:app:dexDebug’.

> com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process ‘command ‘C:Program FilesJavajdk1.7.0_79binjava.exe” finished with non-zero exit value 2

what is that mean

Sad And Smile
Sad And Smile
5 years ago

First of all, this is one of the best tutorial for implementing parse in Android app. But I have one issue, for me push notification is working fine but Its not displaying in listview.

Ahmed Turk
Ahmed Turk
5 years ago
Reply to  Sad And Smile

it will be displayed only when you use json parse , use jason {
“data”: {
“message”: “Hello! Welcome to parse notifications.”,
“title”: “AndroidHive”
},
“is_background”: false
}

Gergis Fawzy Caesar
Gergis Fawzy Caesar
5 years ago
Reply to  Ahmed Turk

please reply on my problem

I made the project with minimum sdk 10

and make all the steps but this appear to me ”

Error:Execution failed for task ‘:app:dexDebug’.

> com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process ‘command ‘C:Program FilesJavajdk1.7.0_79binjava.exe” finished with non-zero exit value 2

.

Sad And Smile
Sad And Smile
5 years ago

This problem arise when u add wrong dependencies in build.gradle file. If u add more than one dependencies, Better remove it one by one and check it. If not post the dependencies here.

Sad And Smile
Sad And Smile
5 years ago
Reply to  Ahmed Turk

Bro I tried that, but still its not working. But I am able to receive the notification but not the message in listview???

Gergis Fawzy Caesar
Gergis Fawzy Caesar
5 years ago

Error:Execution failed for task ‘:app:dexDebug’.

> com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process ‘command ‘C:Program FilesJavajdk1.7.0_79binjava.exe” finished with non-zero exit value 2

what is that mean

TJ
TJ
5 years ago

This is SO stupid. I do exactly the same in this tutorial, my device registers but my messages don’t even make it to my device. I took out the Notification class because I did not need it.

What I notice is that when it gets registered, my device is missing deviceToken and pushType is undefined. http://gyazo.com/80cea130e8d86ce35ed43179aa9690a2

Can someone please tell me why it is saying this?
The second row is the entries for this exact application

Ravi Tamada
5 years ago
Reply to  TJ

Sometimes the device ID is null in parse dashboard. Even I couldn’t get exact reason. I solved it by uninstalling and installing the app.

Pranav Patel
Pranav Patel
5 years ago

Hello Sir, I am really thankful to you for all of your tutorial even for source code too.But i have one Question and may this is subject for your new tutorial.
How can you compress whole android project and decrease this ,apk file size?
i have download Code for “Android JSON Parsing Tutorial” and whole project around under 100kb and .apk file size is just 16Kb.
Sir,How can it possible and can it possible for android Studio and if possible then please guide me.

Nidhin Kumar
Nidhin Kumar
5 years ago

Hello,
Once the notification is received in listview ,when i press the content in the list view it should start an activity.for that what i have to do

Nidhin Kumar
Nidhin Kumar
5 years ago

Hello,
I am getting notifications but it is not displaying in list view.i used json to send push notification but still i didn’t receive the notification in listview. it shows only a white screen.

badname
badname
5 years ago

hi ravi i have different question , how can i see ( or send ) a float number for example light sensor float number live to other device from internet , or see it on a page in my server , i know some about conecting with sql server and retrofit library , can make this with fast send and refresh it very fast , but need better idea for make this live can help me ?
#LivePostData
#RealTimeDataTransfer

Neeraj Paliwal Paliwal
Neeraj Paliwal Paliwal
5 years ago

pls tutorial on
Traccar Client for Android from https://www.traccar.org

how to use and how is work

Sowmya Karaba
Sowmya Karaba
5 years ago

hi ravi,

I am getting null pointer exception @ editor.putBoolean(IS_LOGIN,true); have followed every single step of this tutorial but I m getting this error can u help me.

Thanks in advance

Mohammad
Mohammad
5 years ago

Thanks Ravi , good explanation.

Manjunath Hegade
Manjunath Hegade
5 years ago

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ‘:app:dexDebug’.
> com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process ‘command ‘/usr/lib/jvm/java-7-openjdk-i386/bin/java” finished with non-zero exit value 2

* Try:
Run with –stacktrace option to get the stack trace. Run with –info or –debug option to get more log output.

I got this error while debugging . I am new to android. please help.

Arya
Arya
5 years ago

Hi Ravi

Based on your (demo) video around 4:39, you’re trying to push the message while the app is closed. (it was a success) that message is shown at the notification area but it won’t show on the list view. Any idea to show the message on the list view after you tap the notification?

Thank you and Keep up the good work

Arya
Arya
5 years ago
Reply to  Arya

I do exactly like the tutorial said, except it keeps giving me error on

//noinspection SimplifiableIfStatement
if (id == R.id.action_logout)

Have no idea about it, because I can only find the action_logout on strings.xml

however I changed the action_logout into action_bar to solve the error message (not sure though) and try to get the apk from the app/outputs/apk and the apk can’t be installed.

I couldn’t run on emulator because I have AMD chipsets

vanderson silva
vanderson silva
5 years ago

Ravi, thank you very much! Great tutorial.

This saves me a lot of time.

Arya
Arya
5 years ago

can you run the app on your device?

vanderson silva
vanderson silva
5 years ago
Reply to  Arya

Yes, for sure. I’ve tested on Android 4.4 and 5.0.

Now I’m making a ‘integration’ with Intel Edison (IOT platform) using the Embedded C SDK. I mean, my Edison board send notifications for my mobile app.

Ravi Tamada
5 years ago

Cool. Great stuff 🙂

Arya
Arya
5 years ago

Sorry for the late reply.
May I know what version of Android Studio that you’re using? was there some additional SDK installed?

I tried to follow the tutorial but it show some errors I can’t solve yet. I suspect there are problems on my machine.

Ravi Tamada
5 years ago
Reply to  Arya

What are the errors?

Arya
Arya
5 years ago
Reply to  Ravi Tamada

@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();

//noinspection SimplifiableIfStatement
if (id == R.id.action_logout) {

my android studio can’t find the “action_logout” so it gives error “cannot resolve symbol action_logout”

I’m at lost now don’t know what I missed

Ravi Tamada
5 years ago

You are welcome 🙂

Edwin Hernández
Edwin Hernández
5 years ago

Hi!

i have a problem. my push is only submitted to my emulator, not in my device. And the DeviceToken is null. Please help me.

Minal Juadli
Minal Juadli
5 years ago

thank you ravi tamada 😀

Ravi Tamada
5 years ago
Reply to  Minal Juadli

You are welcome 🙂

chetan chavan
chetan chavan
5 years ago

Hello Ravi,
How can do the same in Eclipse ? Is it possible in Eclipse ?

Jinson K V
5 years ago
Reply to  chetan chavan

You better move to AS

Anil
Anil
5 years ago

Hello Ravi ,

Can you send me any example to use parseAdapter with recyclerview and card.

ivan louis
ivan louis
5 years ago

hey ravi i wanted to develop an app which registers employees with just their finger print on their phone

Naveen Mishra
Naveen Mishra
5 years ago

Ravi I think we should use default GCM else of this as now GCM gradle is having less stepss than it..

شبير البلوشي
شبير البلوشي
5 years ago

Thanks a ton. it works like a charm. but i have a problem sir. i’m not able to get list in my activity. y is that ? because i followed your complete tutorial A-Z. can u help me in that. ? thanks in advance

Ravi Tamada
5 years ago

Do you see any error in logcat? Also try to keep few messages in list view in main activity and verify whether your list is actually working or not.

شبير البلوشي
شبير البلوشي
5 years ago
Reply to  Ravi Tamada

Push received: {“alert”:”Check Notification.”,”push_hash”:”1b6a47fe998fba5a4c5c4803cb054992″}

Push message json exception: No value for is_background

i’m getting these msgs. i,m getting notification. when i click on it first thing it’s not taking me to my desired activity. second the activity is empty.

Ravi Tamada
5 years ago

Your json is missing is_background node which indicates visibility of notification in notification bar.

Add is_background:true in your json.

This json should be in below format.
{
“data”: {
“message”: “Check Notification.”,
“title”: “AndroidHive”
},
“is_background”: false
}

شبير البلوشي
شبير البلوشي
5 years ago
Reply to  Ravi Tamada

i will try that. another question. i know its dumb but i’m pretty new to android studio. so i don’t know how to add json in my project. can you help me in that? . thanks

Ravi Tamada
5 years ago

What do you mean by adding json in the project?

شبير البلوشي
شبير البلوشي
5 years ago
Reply to  Ravi Tamada

i mean i don’t know where to write is_background code in my project. in any java class or somewhere else.

Ravi Tamada
5 years ago

Where you are posting this json ?

{“alert”:”Check Notification.”}

شبير البلوشي
شبير البلوشي
5 years ago
Reply to  Ravi Tamada

i’ve created a text file in assets folder and posting the json there.

Ravi Tamada
5 years ago

Okay. Then you have to learn how to load a file from assets folder.

Try this
http://stackoverflow.com/questions/16110002/read-assets-file-as-string

Trey Rosius
Trey Rosius
5 years ago

Hi Ravi.I’m trying to implement notifications in my REST API using slim.But i’m confused on creating the notification table, and also, how i can connect it with Parse Notification.I don’t need any code help.I know all the answers are here.Can u please clarify me a little bit on this.

Ravi Tamada
5 years ago
Reply to  Trey Rosius

The tutorial already has the all the php code needed. All you need to do is just merge it with your Slim project.

This can help you
http://www.androidhive.info/2014/01/how-to-create-rest-api-for-android-app-using-php-slim-and-mysql-day-23/

Trey Rosius
Trey Rosius
5 years ago
Reply to  Ravi Tamada

trust me, i literally sleep on your code.My problem is, if i send the notifcation to all users, using parse, how do i register the read/ unread receipts for those notification.Say i want to issue a notification to all users subscripted to a task i created, that’s easy with Parse.But how do i record the fact that, some have read the notifications and others haven’t.(Read receipts).
I don’t know if i’m clear enough.

Ravi Tamada
5 years ago
Reply to  Trey Rosius

Parse provides stats of how many opened the notification, but not sure they do have for individual user.

The solution is, whenever user open the notification, you need to make a call to your server about read/unread status.

You need call below line to see the opened stats on parse dashboard.
ParseAnalytics.trackAppOpenedInBackground(getIntent());

If you want to track individual open rates, check any of the below points.

1. Parse provides a callback method whenever push is opened. (But this method never called for me. See if it can be useful for you)

@Override
protected void onPushOpen(Context context, Intent intent) {
super.onPushOpen(context, intent);
}

2. Another way is in your activity onCreate method, check whether user is coming to from push notification or not. If yes, make a call to server mark the notification read by the individual user.

Trey Rosius
Trey Rosius
5 years ago
Reply to  Ravi Tamada

Thank You soo much.I’ll try those.Else i will stick to your tutorial on GCM.
Thanks Again

Ravi Tamada
5 years ago
Reply to  Trey Rosius

It’s better you follow the GCM in android docs. Mine is very old.

Trey Rosius
Trey Rosius
5 years ago
Reply to  Ravi Tamada

Ok.. i will.Thanks a lot.Your doing a great job

Sarathi Manivel
Sarathi Manivel
5 years ago

Parse push notification worked in emulator, but not work in real device. plz help me

Ahmad Alkhateeb
5 years ago

me 2

Noa
Noa
5 years ago

Did you overcome this problem? I have the same issue 🙁

Ahmad Alkhateeb
5 years ago
Reply to  Noa

unfortunately no. but i noticed that if u now trying to register new device [choose another android mobile i mean different device from ur family or ur friends] it will works fine and also your mobile will receive notification too. i don’t know why did that worked.

Ahmad Alkhateeb
5 years ago

:disqus
Works in emulators,but not working in read devices
help us :(.

Ravi Tamada
5 years ago

Uninstall the app from the device and reinstall it again. Also delete all the device information from parse Core dashboard.

Ahmad Alkhateeb
5 years ago
Reply to  Ravi Tamada

Thanks for ur fast reply
but didn’t work 🙁

Rian Erlangga
Rian Erlangga
5 years ago

Hi Ravi , How can i get ObjectId??

houston49
houston49
5 years ago

Hi Ravi.. My question is how do you make it start another activity and put the notifications there instead of starting the MainActivity? I am mixing things like your NavFragment Drawer, Facebook Like Listview etc on my Main Activity and I was hoping to open this push notification in the NotificationsActivity instead. Thanks for all the help 🙂

Ahmed Shabaan
Ahmed Shabaan
5 years ago

i have link that return the same json format how can use it in parse.com without copying and paste json code

Jaye
Jaye
5 years ago

Hi! can you have a tutorial using PHP as the REST server?

Jaye
Jaye
5 years ago
Reply to  Ravi Tamada

Does parse has a way of identifying different clients? Like you only want to send to select devices and not all? GCM has a registration id for every device? Does Parse have this kind of feature?

ragunath
ragunath
5 years ago

Hi,Please help me…if was send push notification through parse.com the device only notify toolbar.
my problem is when i was click notification message in toolbar it will open blank activity the notification message doesn’t to view???

Also if the main activity viewing to be sending push notification appear on that activity.

ragunath
ragunath
5 years ago

Hi,Please help me…if was send push notification through parse.com the device only notify toolbar.
my problem is when i was click notification message in toolbar it will open blank activity the notification message doesn’t to view???

Also if the main activity display through parse.com push to be sending message notification appear on that activity.

ragunath
ragunath
5 years ago

hi i can get push notification in toolbar.when i was click notification it will show empty activity.
also if activity open means send message it display the activity to view
please help me click notify message the tool bar to view main activity.

Shashank Gupta
Shashank Gupta
5 years ago

hi,i want to add new column in installation table so that i can filter and send notification.How can I achieve this? Thanks in advance..

Jaymo Left Brained
Jaymo Left Brained
5 years ago

Consider adding for lower API levels as the method isAppIsInBackground(Context context) requires it

Ravi
Ravi
5 years ago

Hi Ravi!,
Thanks for share this.
I m getting notification in Android Kit-kat but not in lollipop. please help me.

Rex
Rex
5 years ago

hi Ravi receiving notification twice one is our custom notification and i dont know why is it showing another notification

Bernardus Dominicus
Bernardus Dominicus
5 years ago

I already implement this tutorial… It works well…. but… on some record at parse.com dashboard….
I have 400 record with no deviceToken…. what’s wrong with this?? is anyone has same problem with me?? any solution?? thank you

vikasvmane
vikasvmane
5 years ago

How to send parse push message to a particular user?

Ravi Tamada
5 years ago
Reply to  vikasvmane

Check the demo video. I have sent message to individual by their email.

shubham
shubham
5 years ago

App shows “succesfully registered with parse” in logcat. But parse dashboard shows no registered devices.

193
0
Would love your thoughts, please comment.x
()
x