in src/Google.Cloud.Functions.Framework/GcfEvents/GcfConverters.cs [517:547]
protected override void PopulateAttributes(Request request, CloudEvent evt)
{
// We need the event name and the app ID in order to create subject and source like this:
// Subject://firebaseanalytics.googleapis.com/projects/{project}/apps/{app}
// Source: events/{eventName}
// The eventName is available in the resource, which is of the form projects/{project-id}/events/{event-name}
// The app name is available via the data, via userDim -> appInfo -> appId
// If either of these isn't where we expect, we throw a ConversionException
string resource = request.Context.Resource.Name!;
string service = request.Context.Resource.Service!;
var data = request.Data;
string[] splitResource = resource.Split('/');
string? eventName = splitResource.Length == 4 && splitResource[0] == "projects" && splitResource[2] == "events" ? splitResource[3] : null;
string? appId = data.TryGetValue("userDim", out var userDim) && userDim is JsonElement userDimElement &&
userDimElement.TryGetProperty("appInfo", out var appInfoElement) &&
appInfoElement.TryGetProperty("appId", out var appIdElement) &&
appIdElement.ValueKind == JsonValueKind.String
? appIdElement.GetString() : null;
if (eventName is object && appId is object)
{
string projectId = splitResource[1]; // Definitely valid, given that we got the event name.
evt.Source = new Uri($"//{service}/projects/{projectId}/apps/{appId}", UriKind.RelativeOrAbsolute);
evt.Subject = $"events/{eventName}";
}
else
{
throw new ConversionException("Firebase Analytics event does not contain expected data");
}
}