node.jspromiseparse-serverafter-save

Using Promise in afterSave


I am trying to do the following code in cloud code:

    //Code for sending push notifications after an update is created
Parse.Cloud.afterSave('AssignmentMod', function(request){
  //Only send if the mod is new
  console.log("MOD SAVED. NOTIFICATIONS CHECK.")
  if(!request.object.existed()) {
    console.log("NEW MOD ADDED. NOTIFICATIONS START.")
    var mod = request.object

    //Get the users who have these classes
    var userType = Parse.Object.extend('User')
    var usersQuery = new Parse.Query(userType)
    usersQuery.equalTo('currentClasses', mod.get("parentClass"))

    //Get the users who removed the assignment
    var modsType = Parse.Object.extend('AssignmentMod')
    //If if was an assignment and removed at some point
    var mods1Query = new Parse.Query(modsType)
    mods1Query.notEqualTo("assignment", null)
    mods1Query.equalTo("assignment", mod.get("assignment"))
    mods1Query.equalTo("type", "remove")
    //If it was an assignment mod and was removed at some point
    var mods2Query = new Parse.Query(modsType)
    mods2Query.notEqualTo("assignmentMod", null)
    mods2Query.equalTo("assignmentMod", mod.id)
    mods2Query.equalTo("type", "remove")
    //Get the remove mods for this particular update
    var modsQuery = new Parse.Query.or(mods1Query,mods2Query)

    //Run the user and mods queries
    Parse.Promise.when(
      usersQuery.find(),
      modsQuery.find()
    ).then( function(users, removeMods) {
      console.log("QUERY 1 COMPLETE.")
      //Get all users that copied this remove mod
      var copyType = Parse.Object.extend('ModCopy')
      var copyQuery = new Parse.Query(copyType)
      copyQuery.containedIn("assignmentMod", removeMods)
      copyQuery.find().then(function(copies){
        console.log("QUERY 2 COMPLETE.")
        var copyUsers = copies.map(function(copy){
          return copy.get("user")
        })

        //Get the devices of users that belong to the class, did not remove the assignment, and have an ios devices
        var deviceQuery = new Parse.Query(Parse.Installation)
        deviceQuery.equalTo("deviceType", "ios")
        deviceQuery.containedIn("user", users)
        deviceQuery.notContainedIn("user", copyUsers)

        //Send the push notification
        console.log("PUSHING NOTIFICATIONS")
        Parse.Push.send(
          {
            where: deviceQuery,
            data: {
              alert: "You have new updates."
            }
          },
          {userMasterKey: true}
        ).then(
          function(){
            console.log("SUCCESSFULLY SEND NOTIFICATIONS.")
          },
          function(error){
            throw "Error sending push notifications:" + error.code + " : " + error.message
            console.log("FAILED TO SEND NOTIFICATIONS")
          }
        )

      },
      function(reason){
        throw "Error: " + reason
        print("ERROR: " + reason)
      })

    },
    function(reason){
      throw "Error: " + reason
      print("ERROR: " + reason)
    })

  }

})

I can see in my logs that "MOD SAVED. NOTIFICATIONS CHECK." and "NEW MOD ADDED> NOTIFICATIONS START." are both logged out. However, I get no other logs after that and no push notifications are sent. I should at leas see the logs, and see none. Is there an issue with parse server using promises inside an afterSave or something? Why am is my code seemingly halting execution when it hits the first promise?


Solution

  • This turned out to be an issue with Heroku hosting. I have not tracked down passed that. If the same code is hosted on AWS or another hosting platform, these issues do not occur. There is likely some server settings Heroku uses in it's default setup that need changed. If you encounter this issue and have more of a solution beyond "Switch off Heroku hosting" then submit an answer and I will accept.