0

I am having a problem to understand what am I missing on my server side. I am sending a firebase function delete request to my Node JS server from Android client side and when printing to console everything looks fine and works synchronously and ends with status code 200, but I am getting the String cannot be converted to JSONObject error at the android side. What am I missing in my node js code?

here is my Android client side code -


private void deleteCurrentVideo(int position) {
        //setProgressBarVisibility(View.GONE, View.VISIBLE);
        ProgressDialog dialog = new ProgressDialog(getContext(),R.style.DialogTheme);
        dialog.setMessage("Please wait");
        dialog.setCancelable(false);
        dialog.show();
        Map<String,Object> data = new HashMap<>();
        data.put("videoId",mVideoKey);
        data.put("cloudinaryId", mCloudinaryId);
        data.put("contestId", mContestKey);
        FirebaseFunctions.getInstance()
            .getHttpsCallable("https_delete_video_request")
            .call(data)
            .addOnCompleteListener(task -> {
                if (task.isSuccessful()) {
                    if (task.isComplete()) {
                        mVideoDeletedListener.onVideoDeleted(position);
                        dialog.dismiss();
                    }
                } else {
                    Toast.makeText(getContext(),"Error deleting video", Toast.LENGTH_SHORT).show();
                }
            });

    }

and here is my firebase function code -



exports.https_delete_video_request = functions.https.onRequest((req, res) => {
  const videoId = req.body.data.videoId;
  const cloudinaryId = req.body.data.cloudinaryId || "null";
  const contestId = req.body.data.contestId;

  console.log("Request body:", req.body);

  console.log("inside delete video function with the following videoID " + videoId);
  console.log("inside delete video function with the following cloudinaryId " + cloudinaryId);
  console.log("inside delete video function with the following contestId " + contestId);

  if (!videoId && !cloudinaryId && !contestId) {
    return res.status(400).send("Bad Request: Maybe you are missing some required parameters");
  }

  return moddelete.deleteVideoFromCloudinary(cloudinaryId, videoId,contestId, res, function(result) {
      console.log(result);
  });
});


here is my deletion module -


// define global varibales
const admin = require('firebase-admin');
const database = admin.database();
const cloudinary = require('cloudinary').v2

// variables for getting the cloudinary sensitive information
const content = require('./cloudinary-account.json');


//this is the inital deletion method - it deleted the video from cloudinary, if it works successfully it continues to delete from firebase database. 
//this is stage 1/3 of the deletion.
exports.deleteVideoFromCloudinary = function (cloudinaryId, videoId, contestId, response, callabck) {
    if (cloudinaryId === null) {
        return;
    }

    //initially create the map without any key
    var map = {};

    function addValueToList(key, value) {
        map[key] = map[key] || [];
        map[key].push(value);
    }

    addValueToList("api_secret", content.cloudinary_api_secret);
    addValueToList("api_key", content.cloudinary_api_key);
    addValueToList("resource_type", content.cloudinary_resource_type);
    addValueToList("cloud_name", content.cloudinary_cloud_name);

    cloudinary.uploader.destroy(cloudinaryId, map, function (error, result) {
        if (error !== undefined) {
            console.log("cloudinary error - " + error);
            callabck(error);
            return response.status(500).send("");
        }

        console.log("cloudinary result - " + JSON.stringify(result));
        continueDeleteFromFirebaseVotesDB(videoId, contestId, response, function(result){
            callabck("successfully deleted from cloudinary")
            console.log(result);
            return response.status(200).send(JSON.stringify("success"));
        }) ;
    });
}

//this is a function that deletes the votes associated with the deleted video.
//this is stage 2/3 of the deletion.
function continueDeleteFromFirebaseVotesDB(videoId, contestId, response, callabck) {
    var query = database.ref("votes/" + contestId).orderByKey();
    console.log(JSON.stringify(query));
    query.once("value")
        .then(function (snapshot) {
            if (!snapshot.exists) {
                // console.log("votes db snapshot does not exist");
                callabck("votes db snapshot does not exist")
                return;
            }
            console.log("entire snapshot - " + JSON.stringify(snapshot));
            snapshot.forEach(function (childSnapshot) {
                //var key = childSnapshot.key;
                // childData will be the actual contents of the child
                var childData = childSnapshot.val();
                if (childData.video_id !== videoId) {
                    //console.log("nothing to delete");
                } else {
                    childSnapshot.ref
                        .remove()
                        .then(function () {
                            console.log("removed vote successfully - " + JSON.stringify(childSnapshot))
                            return null;
                        })
                        .catch(function (error) {
                            console.log("vote remove failed: " + error.message)
                            response.status(500).send("");
                        });
                }
            });
            continueDeleteFromFirebaseVideosDB(videoId, response, function(result) {
                callabck("successfully deleted from votes database");
                console.log(result);
            })
            return query;

        })
        .catch(error => {
            // console.log("votes query error " + JSON.stringify(error))
            callabck("votes query error " + JSON.stringify(error))
            response.status(500).send("");
        })
}

//this is the last function that deletes the actual video from Videos table itself. 
//this is stage 3/3 of the deletion. 
function continueDeleteFromFirebaseVideosDB(videoId, response, callabck) {
    var query = database.ref("videos/" + videoId).orderByKey();
    console.log(JSON.stringify("videos DB query - " + query));
    query.once("value")
        .then(function (snapshot) {
            if (!snapshot.exists) {
                // console.log("video snapshot does not exist");
                callabck("video callback - video snapshot does not exist")
                return;
            }
            console.log("Videos DB snapshot - " + JSON.stringify(snapshot));
            snapshot.ref.remove()
                .then(function () {
                    // console.log("removed video successfully - " + JSON.stringify(snapshot))
                    callabck("successfully deleted from videos database")
                    return null;
                })
                .catch(function (error) {
                    console.log("video remove failed: " + error.message);
                    callabck("video callback - video remove failed: " + error.message);
                    response.status(500).send("");
                });
            return query;
        })
        .catch(error => {
            // console.log("videos query error " + JSON.stringify(error))
            callabck("videos query error " + JSON.stringify(error));
            response.status(500).send("");
        })
}


at the end I am getting at the function console the following messages -

enter image description here

Alon Shlider
  • 1,187
  • 1
  • 16
  • 46

1 Answers1

0

Found the answer - quit Javascript.

And in a more practical manner - when I was posting the following code -

return response.status(200).send("success");

Android was not able to get a JSON object out of it. Not even when doing JSON.stringify("success"). So my solution was the following code -

return response.status(200).send('{"result": "success"}');
Alon Shlider
  • 1,187
  • 1
  • 16
  • 46