Webhook PATCH request type

Hello, I would like to ask if there is any possible way to use PATCH as a request type in integration webhook. I am trying to update document in Firestore database.

I can see only predefined options for POST, GET, PUT, DELETE, but I found out there is possibility to rewrite request type in custom template. It partialy works, my request is trully of type PATCH (as I can see in Logs), but it sends request without json in body.

Custom template (for testing purpose, I will change data to be send later)

{
    "event": "update_device_state",
    "url": "https://firestore.googleapis.com/v1beta1/projects/vivarium-control-unit/databases/(default)/documents/users/XXX/devices/YYY?updateMask.fieldPaths=state",
    "requestType": "PATCH",
    "noDefaults": true,
    "rejectUnauthorized": true,
    "json": {
        "fields": {
            "state": {
                "mapValue": {
                    "fields": {
                        "temp_1": {
                            "doubleValue": 1111.1
                        },
                        "temp_2": {
                            "doubleValue": 22222.3
                        },
                        "another_state": {
                            "stringValue": "test"
                        }
                    }
                }
            }
        }
    }
}

I can save this request and all looks good until I try to test query. Then body is removed from my webhook.

Request

PATCH /v1beta1/projects/vivarium-control-unit/databases/(default)/documents/users/XXX/devices/YYY?updateMask.fieldPaths=state HTTP/1.1
User-Agent: ParticleBot/1.1 (https://docs.particle.io/webhooks)
host: firestore.googleapis.com
content-type: application/x-www-form-urlencoded
content-length: 0
Connection: keep-alive

Response is HTTP/1.1 200 OK, but state field from Firestore is completely removed because of empty body.

So my question: is there any way how to use request type PATCH properly or do I have to find some workaround on Firestore side (like sending POST to recreate whole document and handle this request by cloud functions)?

Thank you kindly for any sort of advice.

I have no idea whether PATCH is supported at all, but doubt it.

However, can you try this?

{
    "event": "update_device_state",
    "url": "https://firestore.googleapis.com/v1beta1/projects/vivarium-control-unit/databases/(default)/documents/users/XXX/devices/YYY?updateMask.fieldPaths=state",
    "requestType": "PATCH",
    "noDefaults": true,
    "rejectUnauthorized": true,
    "headers": {
        "Content-Type": "application/json"
    },
    "body": "{\"fields\":{\"state\":{\"mapValue\":{\"fields\":{\"temp_1\":{\"doubleValue\":1111.1},\"temp_2\":{\"doubleValue\":22222.3},\"another_state\":{\"stringValue\":\"test\"}}}}}}"
}

Just tested against requestbin.com and I think PATCH is not supported - @rickkas7?

Thank you for your reply.
Sadly, outcome is the same as when I used “json” in template. You might be right that PATCH is not supported. I didn’t find any mention of it in docs. I was just keeping my hopes up because the PATCH request is actually working and it can erase my data in firestore (as it would do with empty body).

Have you tried PUT?
PUT should also be able to remove an entry.

Unfortunatelly, PUT is not supported by Firestore

I am not sure what you mean by removing an entry, but I probably mispoke my intence in previous reply.
I am trying to update document field state, but PATCH request from Webhook removes that field instead - so I know (or I think I know) webhook is somehow able to send PATCH request, but it is not sending the body right or at all. When I try to send same request from postman, it works as it should work and state is updated.

Hello again.
I managed to write a workaround with sending POST request to create new document in firestore database and I would like to share my solution for others. I wrote script on Firestore side (Cloud functions for Firebase) which takes created data and update document with right documentId.

https://firestore.googleapis.com/v1beta1/projects/vivarium-control-unit/databases/(default)/documents/users/{{{userId}}}/devices?documentId={{{deviceId}}}{{{updateRequestCount}}}

Because I create new document each time and cloud functions can take some time to finish, I have to make sure that documentId is different for every request - updateRequestCount

JSON body of WEBOOK:

          
{
  "fields": {
    "sensorValues": {
      "mapValue": {
        "fields": {
          "temp_1": {
            "doubleValue": "{{temp1}}"
          },
          "temp_2": {
            "doubleValue": "{{temp2}}"
          }
        }
      }
    },
    "deviceId": {
      "stringValue": "{{deviceId}}"
    },
    "updateData": {
      "booleanValue": true
    }
  }
}

Function of firebase side:

exports.updateSensorValues = functions.firestore
    .document('users/{userId}/devices/{newDeviceId}')
    .onCreate(async (snap, context) => {
        const data = snap.data();
        if (!data) {
            return null;
        }
        const sensorValues: any     = data.sensorValues;
        const deviceId: string      = data.deviceId;
        const newDeviceId: string   = context.params.newDeviceId;
        const userId: string        = context.params.userId;

        if (!data.updateData || !sensorValues || !deviceId) {
            return null;
        }
        const promises = []; 
        promises.push(updateDeviceSensorValues(userId, deviceId, sensorValues));
        promises.push(removeNewDevice(userId, newDeviceId));
        return Promise.all(promises)
            .then(() => {
                return "ok";
            }).catch(errPromises => {
                return "error";
            });

    });

function updateDeviceSensorValues(userId: string, deviceId: string, sensorValues: any) {
    sensorValues['updateTime'] = admin.firestore.Timestamp.now();
    return admin.firestore().collection('users').doc(userId)
        .collection('devices')
        .doc(deviceId)
        .update({sensorValues: sensorValues});
}

function removeNewDevice(userId: string, deviceId: string) {
    return admin.firestore().collection('users').doc(userId)
        .collection('devices')
        .doc(deviceId)
        .delete();
}

Of course it would be better to use Webhook with PATCH, but at least this way everything works fluently.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.