3

In my app, users create posts and I'd like to show trending posts by the number of views, comments, etc in a specific date range. To do that I thought I can create a custom event as below:

await FirebaseAnalytics.instance.logEvent(
    name: "trending_contents",
    parameters: {
      "content_type": EnumToString.convertToString(type),
      "content_id": contentModel.externalId,
      "action_type": "post",
      "point": 3,
    },
  );

I wonder if it is possible to use Google Analytics Data API to get trending posts by a specific date range? Or is there any better way to get trending posts instead of google analytics data API?

anilcngz
  • 101
  • 3
  • 9
  • you should take a look at Google tag manager instead. https://developers.google.com/tag-platform/tag-manager/ – griffins Apr 07 '22 at 18:13

1 Answers1

3

I finally found a solution on how to use Google Analytics Data API to manage trending content. If anyone is looking for a solution for a similar need, here is what I've done so far:

  1. I send a custom event in specific situations such as when the user views the content etc. as below. If you use parameters' names according to predefined dimensions & metrics (see API Dimensions & Metrics), it will be easy to prepare a custom report (at least it was for me...). Later, I use contentType and contentId as dimensions and eventValue as a metric in the custom report.

     await FirebaseAnalytics.instance.logEvent(
          name: "trending_contents",
          parameters: {
            "content_type": EnumToString.convertToString(event.type),
            "content_id": contentId,
            "action_type": "view",
            "value": 1,
          },
        );
    
  2. Lastly, I created a scheduled cloud function that runs every 6 hours and populates firebase collection according to custom report results. This report gives contentIds in a specific date range ordered by the sum of values that I sent in a custom event

P.S. you need to create a service account in Google Cloud Console, then generate JSON credentials for it and add the file to your project (see credentialsJsonPath variable below). Then you need to add its email address to google analytics 'Property Access Management' section to access analytics data. To see Google Analytics Data API samples, you can check their GitHub repo

    const { BetaAnalyticsDataClient } = require('@google-analytics/data');
    exports.scheduledTrendingFunction = functions.pubsub.schedule('0 */6 * * *').onRun((context) => {
    const propertyId = process.env.GA_PROPERTY_ID;
    const credentialsJsonPath = process.env.GA_CRENDENTIALS_PATH;
    const analyticsDataClient = new BetaAnalyticsDataClient({
        keyFilename: credentialsJsonPath,
    });

    async function runReport(filterType) {
        // [START analyticsdata_json_credentials_run_report]
        const [response] = await analyticsDataClient.runReport({
            property: `properties/${propertyId}`,
            dateRanges: [
                {
                    startDate: '3daysAgo',
                    endDate: 'today',
                },
            ],
            dimensions: [
                {
                    name: 'contentType',
                },
                {
                    name: 'contentId'
                }
            ],
            metrics: [
                {
                    name: 'eventValue'
                },
            ],
            dimensionFilter: {
                andGroup: {
                    expressions: [
                        {
                            filter: {
                                fieldName: "eventName",
                                inListFilter: {
                                    values: ["trending_contents"]
                                }
                            }
                        },
                        {
                            filter: {
                                fieldName: "contentType",
                                inListFilter: {
                                    values: [filterType]
                                }
                            }
                        }
                    ]
                }
            },
            offset: 0,
            limit: 20,
            orderBys: [
                {
                    desc: true,
                    metric: {
                        metricName: "eventValue"
                    }
                }
            ]
        });
        // [END analyticsdata_json_credentials_run_report]

        const batch = admin.firestore().batch();

        // BATCH: delete
        const trendRef = admin.firestore().collection('trends').doc(filterType);
        batch.delete(trendRef);

        const subTrendRef = admin.firestore().collection('trends').doc(filterType).collection('trendContents');
        
        // console.log(response);
        response.rows.forEach((row, index) => {
            // BATCH: add each contentId to trend
            const contentId = row['dimensionValues']['1']['value'];
            batch.set(subTrendRef.doc(contentId), {priority: index + 1});
        });

        // Commit the batch
        await batch.commit();
    }

    runReport("book");

    return null;
    });
anilcngz
  • 101
  • 3
  • 9
  • Your Solution seems quite appealing. But is the firebase Analytics API made for something like this? I am kind of worried to use a quite unpractical approach... – Paul Aug 30 '22 at 21:56
  • I am using this solution for a while in my app, and it works very well for me. I am not sure if Analytics API is made for something like this, but it offers methods in that you can log custom events and get a custom report. This was the best solution I can find @Paul – anilcngz Sep 01 '22 at 07:21
  • I like your solution, it might be quicker. For reference, there is also [another solution](https://stackoverflow.com/a/67907143/11003497), where you could use a priority field. This has the advantage of playing around with retrieving and parameters a bit more. – Paul Sep 01 '22 at 22:40
  • I'll definitely check it, thank you for sharing it @Paul – anilcngz Sep 02 '22 at 09:33