I have a very simple Kotlin/Ktor docker image that does this:
import com.google.events.cloud.firestore.v1.DocumentEventData
fun Application.configureRouting() {
val logger = LoggerFactory.getLogger(javaClass)
routing {
post("/debugfirestore") {
val message = call.receive<ByteArray>()
val data = DocumentEventData.parseFrom(message)
logger.info("documentEventData: $data")
return@post
}
}
}
fun Application.configureSerialization() {
install(ContentNegotiation) {
json()
@OptIn(ExperimentalSerializationApi::class)
protobuf()
}
}
I also have Eventarc and Firestore configured like this:
% gcloud eventarc triggers update my-firestore-update \
--location=nam5 \
--service-account=... \
--destination-run-service=my-prototype \
--destination-run-region=us-central1 \
--destination-run-path="/debugfirestore" \
--event-filters="database=(default)" \
--event-filters-path-pattern="entity=test-collection/**" \
--event-filters="type=google.cloud.datastore.entity.v1.written"
I'm running my app on Google Cloud Run. I can successfully trigger and receive an event but I'm unable to parse the protobuf payload (I think it's protobuf?).
com.google.protobuf.InvalidProtocolBufferException: Protocol message had invalid UTF-8.
at com.google.protobuf.InvalidProtocolBufferException.invalidUtf8(InvalidProtocolBufferException.java:149)
at com.google.protobuf.Utf8$UnsafeProcessor.decodeUtf8(Utf8.java:1365)
at com.google.protobuf.Utf8.decodeUtf8(Utf8.java:318)
at com.google.protobuf.CodedInputStream$ArrayDecoder.readStringRequireUtf8(CodedInputStream.java:788)
at com.google.events.cloud.firestore.v1.Document$Builder.mergeFrom(Document.java:854)
at com.google.events.cloud.firestore.v1.Document$Builder.mergeFrom(Document.java:655)
at com.google.protobuf.CodedInputStream$ArrayDecoder.readMessage(CodedInputStream.java:844)
at com.google.events.cloud.firestore.v1.DocumentEventData$Builder.mergeFrom(DocumentEventData.java:615)
at com.google.events.cloud.firestore.v1.DocumentEventData$1.parsePartialFrom(DocumentEventData.java:1290)
at com.google.events.cloud.firestore.v1.DocumentEventData$1.parsePartialFrom(DocumentEventData.java:1282)
at com.google.protobuf.AbstractParser.parsePartialFrom(AbstractParser.java:135)
at com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:168)
at com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:180)
at com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:185)
at com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:25)
at com.google.events.cloud.firestore.v1.DocumentEventData.parseFrom(DocumentEventData.java:360)
The data that I'm writing to Firestore is simple JSON object without any crazy characters (AFAICT). Why is it complaining about UTF8? I'm guessing there's a problem with the way that I'm trying to parse the request payload OR the response isn't in the format (ByteArray) that I think it is. Where am I going wrong?
edit: I also tried this:
post("/debugfirestore") {
logger.info("Content-Type = ${call.request.contentType()}")
val data = call.receive<DocumentEventData>()
logger.info("documentEventData: $data")
call.respond("$data")
return@post
}
I thought this might work since I have the protobuf() plugin but it fails saying:
Caused by: kotlinx.serialization.SerializationException: Serializer for class 'DocumentEventData' is not found.
Further down I see logs saying:
Please ensure that class is marked as '@Serializable' and that the serialization compiler plugin is applied.
The issue is that I needed to use EntityEventData
instead of DocumentEventData
.
Thanks to DazWilkin for the answer.
Side note, using the kotlinx-serialization way doesn't seem to work for me here because, I think, neither EntityEventData
nor DocumentEventData
are @Serializable
.