6

I know this is a simple question but I am new here. Can I know whether there is any option to send push notification from google cloud(backend, java server) to devices(Android) every 3rd month till end date. If so how?? and can I trigger repeating notification for an interval of time??

In my android app(client) I have these classes https://github.com/googlesamples/google-services/tree/master/android/gcm/app/src/main/java/gcm/play/android/samples/com/gcmquickstart

then I made a backend in java and I have these classes there:

public class RegisterUserDetails {

public String RegisterUserDetails(String  data) {
    DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
    Entity fdUsers = new Entity("fdUser");
    Logger log = Logger.getLogger(RegisterUserDetails.class.getName());
    log.setLevel(Level.INFO);
    JsonElement jsonElement = new JsonParser().parse(data);
    JsonArray jsonArray = jsonElement.getAsJsonArray();
   // JsonObject jsonObject = jsonArray.get(0).getAsJsonObject();

    String regId = jsonArray.get(0).getAsString();
    String userName = jsonArray.get(1).getAsString();

    log.info("regId"+regId);
    log.info("userName"+userName);

    fdUsers.setProperty("regId", ""+regId);
    fdUsers.setProperty("userName", ""+userName);
 //   fdUsers.setProperty("userName", "" + userName);

    datastore.put(fdUsers);
    return "Success";
}
}

and I have

import com.google.android.gcm.server.Constants;
import com.google.android.gcm.server.Message;
import com.google.android.gcm.server.Result;
import com.google.android.gcm.server.Sender;
import com.google.api.server.spi.config.Api;
import com.google.api.server.spi.config.ApiNamespace;

import java.io.IOException;
import java.util.List;
import java.util.logging.Logger;

import javax.inject.Named;

import static com.tiya.accountbook.backend.OfyService.ofy;

/**
 * An endpoint to send messages to devices registered with the backend
 * <p/>
 * For more information, see
 * https://developers.google.com/appengine/docs/java/endpoints/
 * <p/>
 * NOTE: This endpoint does not use any form of authorization or
 * authentication! If this app is deployed, anyone can access this endpoint! If
 * you'd like to add authentication, take a look at the documentation.
 */
@Api(
        name = "messaging",
        version = "v1",
        namespace = @ApiNamespace(
                ownerDomain = "backend.accountbook.tiya.com",
                ownerName = "backend.accountbook.tiya.com",
                packagePath = ""
        )
)
public class MessagingEndpoint {
    private static final Logger log = Logger.getLogger(MessagingEndpoint.class.getName());

    /**
     * Api Keys can be obtained from the google cloud console
     */
    private static final String API_KEY = System.getProperty("gcm.api.key");

    /**
     * Send to the first 10 devices (You can modify this to send to any number of devices or a specific device)
     *
     * @param message The message to send
     */
    public void sendMessage(@Named("message") String message) throws IOException {
        if (message == null || message.trim().length() == 0) {
            log.warning("Not sending message because it is empty");
            return;
        }
        // crop longer messages
        if (message.length() > 1000) {
            message = message.substring(0, 1000) + "[...]";
        }
        Sender sender = new Sender(API_KEY);
        Message msg = new Message.Builder().addData("message", message).build();
        List<RegistrationRecord> records = ofy().load().type(RegistrationRecord.class).limit(10).list();
        for (RegistrationRecord record : records) {
            Result result = sender.send(msg, record.getRegId(), 5);
            if (result.getMessageId() != null) {
                log.info("Message sent to " + record.getRegId());
                String canonicalRegId = result.getCanonicalRegistrationId();
                if (canonicalRegId != null) {
                    // if the regId changed, we have to update the datastore
                    log.info("Registration Id changed for " + record.getRegId() + " updating to " + canonicalRegId);
                    record.setRegId(canonicalRegId);
                    ofy().save().entity(record).now();
                }
            } else {
                String error = result.getErrorCodeName();
                if (error.equals(Constants.ERROR_NOT_REGISTERED)) {
                    log.warning("Registration Id " + record.getRegId() + " no longer registered with GCM, removing from datastore");
                    // if the device is no longer registered with Gcm, remove it from the datastore
                    ofy().delete().entity(record).now();
                } else {
                    log.warning("Error when sending message : " + error);
                }
            }
        }
    }
}

then what to do??

When a user save an account detail he will save a start date and an end date to the google cloud. I want to send notification to this user every 3rd month from this start date till the end date. Like this there will be many accounts it can be from same user or different. I want to know whether this is possible??? If so how??? –

Elizabeth
  • 1,399
  • 1
  • 13
  • 25
  • You can manage using Schedular in web to get Month Change and according to that you can send pushnotification – Abhishek Patel Mar 29 '16 at 07:03
  • Yes, you can create jobs using Quartz scheduler and schedule it for every month. https://www.quartz-scheduler.org/documentation/quartz-2.2.x/tutorials/tutorial-lesson-01 – Alok Gupta Mar 29 '16 at 07:04
  • can i get any links to tutorials?? as i am just a beginner dont know from where to start..i just got device reg ids from client then stored in data store in google cloud..then i dont know what to do?? – Elizabeth Mar 29 '16 at 07:06

4 Answers4

2

Please use Quartz scheduler and schedule a job to run a particular code every month. You can find the tutorial here: http://www.mkyong.com/java/quartz-scheduler-example/

Alok Gupta
  • 1,353
  • 1
  • 13
  • 29
  • It should be written in your java code i.e. server side. What you can do is, you can create a small test job and schedule it for every 5 minutes by following the tutorial, and then you will be able to verify if push notifications are going in every 5 minutes or not. Hope this helps. – Alok Gupta Mar 29 '16 at 07:14
  • can i add end date here...so that it stops sending notification when it reaches end date?? – Elizabeth Mar 29 '16 at 07:18
  • whether i have to download any lib jar if i am using android studio?? – Elizabeth Mar 29 '16 at 07:37
  • No. You only need to create listeners/receivers, which will receive the push notification, which I think you might have done already. – Alok Gupta Mar 29 '16 at 07:46
  • can you help me in detail – Elizabeth Mar 29 '16 at 07:49
  • I can help but only on weekend. You can get some information about what is receiver etc from http://www.androidhive.info/2016/02/android-push-notifications-using-gcm-php-mysql-realtime-chat-app-part-1/ – Alok Gupta Mar 29 '16 at 07:51
1

If you wanted to send a specific message to all users every month (e.g. on the 1st of the month message all users), you could use a cron job that runs every month.

As documented here: https://cloud.google.com/appengine/docs/java/config/cron

As per the docs, you could say

2nd,third mon,wed,thu of march 17:00
1st monday of sep,oct,nov 17:00
1 of jan,april,july,oct 00:00
TStu
  • 244
  • 3
  • 15
  • when a user save an account detail he will save a start date and an end date to the google cloud. i want to send notification to this user every 3rd month from this start date till the end date. like this there will be many accounts it can be from same user or different. I want to know whether this is possible??? if so how??? – Elizabeth Apr 07 '16 at 04:15
1

You can look at Azure Notifications Hub. https://azure.microsoft.com/en-in/pricing/details/notification-hubs/

Its top offering supports scheduled push messages. Though it is a bit pricey.

Instead, simple logic on server side can also be written to handle recurrence and automatically add message to outgoing push message queue. Hardly a couple of days work.

Abhijit Ajmera
  • 235
  • 2
  • 12
  • i would like to do the second option.. days are not a problem i just want a simple approach... can u help me on this if you dont have any problem...? As i am new to this server side programming...even java..i dont know from where to start even... :( – Elizabeth Apr 13 '16 at 05:39
1

Quartz scheduler is an open source job scheduling library you can schedule your jobs to run from every second to every year see CronTrigger

example: create a trigger create a trigger that fires every half hour between the hours of 8 am and 10 am on the 5th and 20th of every month.

import static org.quartz.TriggerBuilder.*;
import static org.quartz.CronScheduleBuilder.*;
import static org.quartz.DateBuilder.*:

create a trigger

trigger = newTrigger()
.withIdentity("trigger3", "group1")
.withSchedule(cronSchedule("0 0/30 8-9 5,20 * ?"))
.forJob("myJob", "group1")
.build();

simple trigger with start date and end date

Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

    JobDetail job = newJob(TestJob.class)
        .withIdentity("cronJob", "testJob") 
        .build();

    String startDateStr = "2013-09-27 00:00:00.0";
    String endDateStr = "2013-09-31 00:00:00.0";

    Date startDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S").parse(startDateStr);
    Date endDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S").parse(endDateStr);

    CronTrigger cronTrigger = newTrigger()
      .withIdentity("trigger1", "testJob")
      .startAt(startDate)
      .withSchedule(CronScheduleBuilder.cronSchedule("0 0 9-12 * * ?").withMisfireHandlingInstructionDoNothing())
      .endAt(endDate)
      .build();

    scheduler.scheduleJob(job, cronTrigger);
    scheduler.start();
Edalat Feizi
  • 1,371
  • 20
  • 32
  • how to write start date and end date using crontrigger?? – Elizabeth Apr 15 '16 at 05:16
  • this cron expression will fires every half hour between the hours of 8 am and 10 am on the 5th and 20th of every month. – Edalat Feizi Apr 15 '16 at 06:03
  • can you tell me how to write cron expression for start dat 16/04/2016 to end date 16/04/2017 every third month on start day(16)?? i dont understand how to write for this expression?? – Elizabeth Apr 15 '16 at 06:28
  • if your mean is create a job to fire every 3 month,use this expression " 0 0 12 16 1/3 ? * ", but you cannot specify end date of your job but instead it in your server when a job fire check your server current date if between 16/4/2016 and 16/04/2017 then send your notifications – Edalat Feizi Apr 15 '16 at 13:31
  • see http://stackoverflow.com/questions/12584992/how-to-get-current-server-time-in-java – Edalat Feizi Apr 18 '16 at 06:17
  • actually my pblm is that when user saves this data to cloud(which contain dates), i want to save alarm trigger also.this class is called only once when he saves his data to cloud. so that when that date reaches it should automatically push notifications. and it is difficult to check current date afterwards... – Elizabeth Apr 18 '16 at 06:54
  • **quartz will running always on your server** so when you schedule a job to fire every 3 month,when a job is firing check your server current date and time if between 16/04/2016 and 16/4/2017 then send your push notifications... – Edalat Feizi Apr 18 '16 at 09:22
  • In the link which you provided says that "Even so, like SimpleTrigger, CronTrigger has a startTime which specifies when the schedule is in force, and an (optional) endTime that specifies when the schedule should be discontinued." that means it supports start date and end date..ri8??? – Elizabeth Apr 18 '16 at 10:44
  • i update the post with a simple trigger with start and end date – Edalat Feizi Apr 18 '16 at 12:14
  • i am getting this error: http://stackoverflow.com/questions/36759822/security-accesscontrolexception-error – Elizabeth Apr 21 '16 at 04:42