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.

Ravi is hardcore Android programmer and Android programming has been his passion since he compiled his first hello-world program. Solving real problems of Android developers through tutorials has always been interesting part for him.
  • Ahmed Turk

    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

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

      • Ahmed Turk

        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

      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

        its kinda simple for you guys but i am still learning so its complicated to me ๐Ÿ˜€

        • Nothing is complicated, all you have to do it practise ๐Ÿ™‚

          • Trey Rosius

            well said Sir….Well Said!

  • Sahitya Kumar Suman

    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

    • Could you explain your problem clearly?

      • Sahitya Kumar Suman

        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.

        • 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

          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

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

      • Sahitya Kumar Suman

        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

    Did this before . nice tutorial anyways. ๐Ÿ™‚

    • Sahitya Kumar Suman

      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

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

  • Thanks ! Will try this out !

  • Yura Ozhyrko

    Do the same by using SignalR library and own server.

  • Krupen Ghetiya

    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

    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

    Thanks, good explanation.

  • Ahmed Turk

    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

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

  • Gon Her

    Excellent tutorial. thank you very much

  • sampath

    getting error at this ParsePush.subscribeInBackground any help ravi…

    • Ahmed Turk

      you used the project in eclipse ?

      • 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

    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

    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

      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

        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

          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

        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

    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

    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

    • 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

    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

    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

    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

    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

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

    how to use and how is work

  • Sowmya Karaba

    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

    Thanks Ravi , good explanation.

  • Manjunath Hegade

    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

    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

      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

    Ravi, thank you very much! Great tutorial.

    This saves me a lot of time.

    • Arya

      can you run the app on your device?

      • vanderson silva

        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.

        • Cool. Great stuff ๐Ÿ™‚

        • Arya

          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.

          • What are the errors?

          • Arya

            @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

    • You are welcome ๐Ÿ™‚

  • Edwin Hernรกndez

    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

    thank you ravi tamada ๐Ÿ˜€

  • chetan chavan

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

  • Anil

    Hello Ravi ,

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

  • ivan louis

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

  • Naveen Mishra

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

  • ุดุจูŠุฑ ุงู„ุจู„ูˆุดูŠ

    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

    • 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.

      • ุดุจูŠุฑ ุงู„ุจู„ูˆุดูŠ

        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.

        • 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
          }

          • ุดุจูŠุฑ ุงู„ุจู„ูˆุดูŠ

            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

          • What do you mean by adding json in the project?

          • ุดุจูŠุฑ ุงู„ุจู„ูˆุดูŠ

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

          • Where you are posting this json ?

            {“alert”:”Check Notification.”}

          • ุดุจูŠุฑ ุงู„ุจู„ูˆุดูŠ

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

          • 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

    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.

    • 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

        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.

        • 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

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

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

          • Trey Rosius

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

  • Sarathi Manivel

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

    • me 2

      • Noa

        Did you overcome this problem? I have the same issue ๐Ÿ™

        • 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.

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

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

  • Rian Erlangga

    Hi Ravi , How can i get ObjectId??

  • houston49

    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

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

  • Jaye

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

  • ragunath

    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

    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

    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

    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

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

  • Ravi

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

  • Rex

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

  • Bernardus Dominicus

    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

    How to send parse push message to a particular user?

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

  • shubham

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

  • Abhishek Kumar

    When i send a push notification to devices , Push Notification is showed at notification bar. But when i click it , it takes me to app but does not show the Notification in List View as shown by you in demo videeo. Please help @ravi8x:disqus

    • Check the logcat for errors.

      • Vinay Mishra

        I am getting the notification when i’m inside the app whereas if i go to another app n send json message from parse i get the json message in notification bar but when i click on the notification listview is not showing anything plz help me as soon as possible

    • Vinay Mishra

      Did u resolve the problem same issure !!!

  • Aasim Shaikh

    how many push notification can be send in one day and to how many users? MycITYNAGPUR

    • Unlimited. The limitation is in the number of requests you send per second.

  • Shashank Gupta

    Message disappears in push notification only tille and icon is visible in version less than lollipop.
    when any other push notification come from any other application,then the message appears.
    Please help me .Do reply me asap.Thanks

    • Willian Serpas

      i have the same issue, anyone can solve this, i’m on api 18

  • Oh, guys, anyone. Can you say why there is a problem with sinch lib in Samsung Lollipop devices and not only Lollipop….

    Service gives an error when starting up….

    2238-2730/com.oombla E/sinch-android-rtc๏น• ERROR: sqlite Failed to exec ‘PRAGMA journal_mode=WAL’, error: database is locked (code: 5, extended code: 5)

  • Prathibha Nandini

    Hello Mr.Tamada…I’m using parse.com.It is working perfectly.For sending notification to my app I’ve used 4 classes from your tutorial. They are:

    1.AppConfig
    2.CustomPushReceiver
    3.NotificationUtils
    4.ParseUtils

    Now am getting notification properly but I have 2 issues.

    1.It is displaying my package name in place of notification title and
    2.onClick on notification it is taking me to dashboard.

    I’ve done the following changes:

    String title = “Prabs”; //in parsePushJson
    Intent resultIntent = new Intent(context, Notification.class); //in parsePushJson
    .setContentTitle(“Prabs”) //in showNotificationMessage

    What changes need to be done to solve these two issues.Kindly help.

    Thank you.

    • Prathibha Nandini

      Mr.Tamada I’ve solved 1st point by adding

      Struggling with 2nd point i.e., onClick on notification it is taking me to dashboard.

      • anuarg0022

        try to fix your pending intent

  • JS Zala

    Hello Ravi,

    I’ve gone through your tutorial and all thing are working fine except deviceToken part.

    I’m unable to see deviceToken, pushType, deviceTokenLastModified at parse.com it says undefined.

    email and all other field are successfully updated.

    Please help!

    Thanks in advance.

    • luks

      have you solved the problem?

      I have the same problem ๐Ÿ™

  • Manny264

    For all still getting errors after logging in or after email has already been supplied,the line below in the MainActivity is the one causing the crash
    setSupportActionBar(mToolbar);

  • Manny264

    Raavi how do you push notifications to only groups of users and not all users?

    • The group of users has to subscribe to a channel. Example if you want to send notifications to users who are interested in Hotels, in the app those users needs to subscribe to a channel called “hotels”.

      You can use below code to subscribe to a channel
      public static void subscribeToChannel(String channelName) {
      ParseInstallation installation = ParseInstallation.getCurrentInstallation();

      installation.put(“channels”, channelName);

      installation.saveInBackground();
      }

      Call like this
      subscribeToChannel(“hotels”);

      • Manny264

        So what you are saying is if channels are defined they will show up on the Parse dashboard and users who subscribe only to these channels will get the messages? How do I add more in the string besides the message?

      • Manny264

        where on the Parse dashboard do I define a channel and the message structure?

  • Harsh

    Hii Ravi.What are the advantages of Parse over GCM for sending push notifications and how many notification we can send at a time to user?

    • Parse is very easy to setup. The admin dashboard is prebuilt. For GCM we need to build everything from scratch like library, admin panel everything, but it is better than Parse (although parse internally uses GCM). Parse has a limit of sending 30notifications / sec.

      • Soham Railkar

        this means If I have 100 users, only 30 users will get notification?

  • Harsh

    In GCM, there is limitation of sending 1000 notifications at a time.so how can i resolve this limitation,bcoz i have developed the app which send notifications to more than 1000 users at a time.please resolve my issue.

  • Ashwin

    Hello I am not receiving any confirmation mail from this website and I’m trying to download this sample code from this page. My mail ID is ashwinsnmv@gmail.com. I hope you fix this ASAP. Thanks in Advance.

  • Okechukwu Eze

    SEND PUSH NOTIFICATION FROM PHP
    …………………………………………………………………………

    ……………..works for me even from localhost…………………………………………..

    array(
    “channels” => $target_device,
    ),
    “data” => array(
    “message” => “second Love message to you”,
    “title” => “second Eze title”
    )
    ));

    $rest = curl_init();
    curl_setopt($rest,CURLOPT_URL,$url);
    curl_setopt($rest,CURLOPT_PORT,443);
    curl_setopt($rest,CURLOPT_POST,1);
    curl_setopt($rest,CURLOPT_POSTFIELDS,$push_payload);

    curl_setopt($rest, CURLOPT_SSL_VERIFYPEER, false); //add to disable SSL Authentication

    curl_setopt($rest,CURLOPT_HTTPHEADER,
    array(“X-Parse-Application-Id: ” . $appId,
    “X-Parse-REST-API-Key: ” . $restKey,
    “Content-Type: application/json”));

    $response = curl_exec($rest);
    echo $response;

    if(curl_errno($rest))
    {
    echo ‘error:’ . curl_error($rest);
    }
    ?>

    • Dimas Andrianto Setiawan

      hi i tried but it shows your code when i ran it on localhost/push.php

      • Okechukwu Eze

        array(
        “channels” => $target_device,
        ),
        “data” => array(
        “message” => “Too much familierity leads to negligency”,
        “title” => “Life tip: True talk!”
        )
        ));

        $rest = curl_init();
        curl_setopt($rest,CURLOPT_URL,$url);
        curl_setopt($rest,CURLOPT_PORT,443);
        curl_setopt($rest,CURLOPT_POST,1);
        curl_setopt($rest, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($rest,CURLOPT_POSTFIELDS,$push_payload);
        curl_setopt($rest,CURLOPT_HTTPHEADER,
        array(“X-Parse-Application-Id: ” . $appId,
        “X-Parse-REST-API-Key: ” . $restKey,
        “Content-Type: application/json”));

        $response = curl_exec($rest);

        echo $response;

        if(curl_errno($rest))
        {
        echo ‘error:’ . curl_error($rest);
        }
        ?>

      • Okechukwu Eze

        array(
        “channels” => $target_device,
        ),
        “data” => array(
        “message” => “Too much familierity leads to negligency”,
        “title” => “Life tip: True talk!”
        )
        ));

  • Okechukwu Eze

    This tutorial is well detailed to me
    But i noticed some little logical issue (Not a bug)

    >>>From my own parse dashboard, i cannot send message to an individual by email since email is not among my push notification conditions

    >>>When i send push to parse server or add a push, it pops up on my devices as a notification.
    When i click on the notification message, it opens the App but displays an empty Activity without the message there. (Checks on the log and cant find any ERROR)

    Even on the video demo (Timeline=> 0:05:18) when the notification hits your devices and you click on them from the notification menu, it also returns to am empty Activity.

    is this a bug or something u left out in ur coding because i feel its very important for the application!

    • Vinay Mishra

      Did u find the soln facing same problem getting empty list view plz help

  • Gpack

    Hello Ravi, isnt nesting Application ID and Client Key a security risk, could someone send messages to my app’s users using them?

  • vikasvmane

    Hey Ravi..Thank you for a wonderful tutorial again…There was a problem i was facing…even if i commented the whole notification method showNotificationMessage,i get the notifcation…i want to customize the notification..please help…thanks

    • anuarg0022

      maybe u have not configured your custom receiver like Ravi did in this tutorial.

  • AndroidDoctorr

    Is there a way to change the color of the circle around the icon in Lollipop?

  • peeyush singhal

    Thank u soo much Ravi !!! . . Great tutorial.

  • Vinicius Delgado

    Ravi my push notification icon is empty, how to change image ?

  • SANDEEP SHAH

    Hi Ravi, I downloaded the Parse Starter project. But I cannot find the Parse 1.9.2.jar file inside it. Could you please help?

  • Anshul Dhingra

    hi ravi i implement this code but parse.com says you hava
    No Registered device can you tell where am going wrong

  • premprakash

    Hi ravi can i test push notification on the emulator or not? please tell me @ravi8x:disqus

  • Parth

    Please remove this ( super.onPushReceive(context, intent);) line in CustomPushReceiver, then created only custom notification in parse 1.10.3

  • Willian Serpas

    Hello, great turorial, thanks a lot, so i get on api 18 notifications just appear the title and icon but the message its empty! just the notification, on listview its ok

  • awdeshbhatti

    Can’t we use Parse Push Notifications with out registering with email id. Is it possible to use it at the background only and with start activity of some other project.

  • awdeshbhatti

    What is required, when we click the push notification, it should open a splash screen or an activity. And email registration is not required. Is it possible to that.

  • Japheth Obala

    Hello @ravi8x:disqus , I have been following along with your tutorial. My App while on the emulator can get notifications but it fails to do so on my device. I downloaded your app and saw that it was receiving notifications both on the device and emulator.
    After googling for possible answers, I found out that a lot of parse users have been having the same issue.
    Did you also have the same issue and if you did, how did you solve it?

  • Joe Miller

    Can you post a tutorial on how to make a chat app with Parse.com?

  • Ramanna Aakasa

    I given my keys in this tutorial …. After push notification send I am getting notification but I am not getting in list ….!

    • Akhil Soman

      In the browser(Parse website) send your Notification text as JSON instead of plain text. Then it will show in your listview.

      • Mohit Khaitan

        I am still not getting it on the list. Can u help ??

  • annapurna podar

    hey !! i have successfully implemented this example but the problem is i m getting notification only in single device. but when i install this app in another device there is no notification. please help me???

  • Narinder Singh

    Hello, Ravi, very good tutorial,

    I just configured the android app and it is working fine, is it possible that when user click on notification, then app should open and show the messages, i know its working when you set is_background : false, but i wanted this functionality with close app too.

  • Vinay Mishra

    Hey ravi how can i show the list when user is redirected from notification bar to main activity ?
    I’m getting the list only when I am on the main screen but as soon as i go to another application and send the push notification its showing me in the notification bar but when i click on the notification i get nothing in the listview ?
    How can i solve this ?

    • Veeresh Charantimath

      You must parse the json in : private void parsePushJson(Context context, JSONObject getJson) to get on tap notification

      • Vinay Mishra

        Thanx ๐Ÿ™‚

      • Vinay Mishra

        But i used sqlite fro the same first stored the message in sqlite den i displayed the same on the main page ๐Ÿ™‚

        • Nishit

          Did Sqlite worked for you??

          • Vinay Mishra

            yes

  • Ibrahim Hassan

    Thanks for this great tutorial.
    I have a problem getting the onPushOpen to work, it seems that it is never called, do you have an explanation?

    • Veeresh Charantimath

      It is called when you tap on the notification in the Status bar

  • Anju Rani

    i cant send push as a json file but i send plain text without any problem.

  • luks

    Hi Ravi, tutorial is awesome ๐Ÿ™‚

    But, i have one problem and i trying for two day.

    My log show this info:

    -Cannot use GCM for push because the app manifest is missing some required declarations. Please make sure that these permissions are declared as children of the root element:
    -Using none for push.

    and this is my manifest:

    http://pastebin.com/WnFdFSht

    i follow your instruction and checked several times but i can’t see any problem.

    Can you please help me?

  • hackerkernel
  • Ashwath

    Guys, this is my code for creating parse notification…i am not able to use setLatestEventInfo method here……

    private void Notify(String notificationTitle, String notificationMessage) { NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); @SuppressWarnings(“deprecation”) Notification notification = new Notification(R.mipmap.ic_launcher, “New Message”, System.currentTimeMillis()); Intent notificationIntent = new Intent(this, NotificationView.class); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); notification.flags |= Notification.FLAG_AUTO_CANCEL;//To close notification after opening notification.setLatestEventInfo(Get_Notification.this, notificationTitle, notificationMessage, pendingIntent); notificationManager.notify(9999, notification); }

  • Shirish Sharma

    Parse.com is going out of service. Can’t Sign Up @ravi8x:disqus Help on this man , how can we replace the existing file with any other free notification provider .

    • You can host the parse services on your own server or you can use GCM for this.

      Please check the site after 3 days. A new GCM post will be published.

      • $|R_MYK3

        how can i host parse services on my own server pls reply

  • Vinay Mishra

    prase is shutting down. do not try ur efforts on parse better go for azure .
    Ravi plz do a tutorial on azure dat would be g8t help thnx ๐Ÿ™‚

    • I’ll check Azure. Thanks Vinay.

      • Vinay Mishra

        Ty for replying ๐Ÿ™‚

  • Harshit Pathak

    Please do a tutorial on AWS.

  • abc

    charkat

  • Sridharan Natarajan

    Mr.Ravi, i want android analytics concept using parser analytics. i get confusion, Can u help me.?

    • Parse is going to shutdown. Do you want to still use it?

      • Sridharan Natarajan

        Oh okay ravi. i need to get app analytical details if any alternative choice avail to fetch the details of app. Please refer me. It will be very helpful to me.

        • Sridharan Natarajan

          Okay , thank you.

      • Sridharan Natarajan

        Oh, okay ravi. i need to get app analytical details if any alternative choice avail to fetch the details of app. Please refer me. It will be very helpful to me .

        • I am not very well choosing the analytics. Try google analytics or Acra.

  • Alex Mugo

    With the Parse Shutdown, what the alternative for PUSH Notifications?

  • Hi,
    any idea how can I use this, is there any chance that I can deploy it on my server ?
    https://github.com/ParsePlatform/parse-server

  • $|R_MYK3

    how do i host parse on my own server

    • Nidhin

      U can try local hosting or use Bitnami Parse to setup on aws

  • Jรขspลซรฑรจรฉt Pรครฑdhรซr

    sir,

    if i open app once… and close it then i again open … the notifiction in app remains??