3

This is the request am making using the UA method of calling the V3 API, wrapped in a oath library for react. But it's getting deprecated starting June 2023 and I can't figure out how to recreate it in the GA4 v1 Beta API aka Google Analytics Data API. I have tried following Google's documentation but i just can't for my life understand how to make the request...

const login = useGoogleLogin({
    onSuccess: async response => {
        try {
             console.log(response.access_token);
            const res = await axios.get(`https://www.googleapis.com/analytics/v3/data/realtime?ids=ga:${gaID}&metrics=rt:activeUsers&access_token=${response.access_token}`, {
                headers: {
                    "authorization": `Bearer ${response.access_token}`
                }
                
                
            })
            if (res.data.rows == null) {
                res.data.rows = 0
            }
            reponseGlobal = response
           
            setactiveUsers(res.data.rows);
            setloggedin(true);
            const interval = setInterval(function() {
                fetch ();
              }, 5000);
          
        } catch (err) {
            console.log(err)
        }
    },
    scope: 'https://www.googleapis.com/auth/analytics.readonly'
});



  
8
  • Have you tried just using the activeUsers metric? Please post your GA4 code and describe what you are trying to extract and what issues you are having. Commented Oct 31, 2022 at 15:07
  • Hey, that's the thing I don't have a GA4 code, Iam trying to write it in GA4 form aka the v1 beta analytics data api from Google. What am trying to extract is is Active users, which is already working in the code above, except it takes the View ID from the Universal Analytics property, the depricated one. And now I need help for someone to write that exact same query(Extract active users) but using the GA4 ID instead the View ID in UA system.
    – Sheru
    Commented Nov 1, 2022 at 8:14
  • Also in your submitted activeUsers link, I have been to the query explorer but unlike the UA one, GA4 only shows a request JSON instead of the HTTP am looking for...
    – Sheru
    Commented Nov 1, 2022 at 8:17
  • Well its hard to help you fix your code if you have no code. Start by seeing if there is even a client library for JavaScript reactJs. I know there is one for node.js Commented Nov 1, 2022 at 8:20
  • GA4 apis are grpc apis they only return json. TBH the reporting api for UA also returned json not sure what you mean by returning html. Commented Nov 1, 2022 at 8:21

2 Answers 2

1

Currently there is no client library client library for react. You may have to code one yourself. The documentation describes all of the calls RunReportResponse

There is a client library for node.js if you could switch to that Node.js quickstart

Remember the API is still in Beta so they are still working on it.

/**
   * TODO(developer): Uncomment this variable and replace with your
   *   Google Analytics 4 property ID before running the sample.
   */
  // propertyId = 'YOUR-GA4-PROPERTY-ID';

  // Imports the Google Analytics Data API client library.
  const {BetaAnalyticsDataClient} = require('@google-analytics/data');

  // Using a default constructor instructs the client to use the credentials
  // specified in GOOGLE_APPLICATION_CREDENTIALS environment variable.
  const analyticsDataClient = new BetaAnalyticsDataClient();

  // Runs a simple report.
  async function runReport() {
    const [response] = await analyticsDataClient.runReport({
      property: `properties/${propertyId}`,
      dateRanges: [
        {
          startDate: '2020-03-31',
          endDate: 'today',
        },
      ],
      dimensions: [
        {
          name: 'city',
        },
      ],
      metrics: [
        {
          name: 'activeUsers',
        },
      ],
    });

    console.log('Report result:');
    response.rows.forEach(row => {
      console.log(row.dimensionValues[0], row.metricValues[0]);
    });
  }

  runReport();

As far as i can see there is no google cloud client library for JavaScript, this is where the data api normally lies. Without there being a client library for cloud i question weather or not they will create a library for JavaScript and reactjs

Update

I sent a message off to the team to ask if they were working on a react.js library for Analytics data api.

The response was that there was no work planed at this time implement a data api library specifically designed for ReactJs

They sugest the google-api-javascript-client Apparntly the GA4 Dimensions & Metrics Explorer uses it with ReactJs. They offer ga-dev-tools and onInitialClientRender.js as an example

1
  • I have updated the answer with the response from the team working on the Google analytics apis. Commented Nov 3, 2022 at 7:22
0

Alright took me a bit of a while to understand but I have gotten the data I was looking for at least, here's the full component for anyone's further use case. The following code takes your GA4 ID and returns the Realtime currently active users in the past 60 seconds. In the full app(Check my GitHub) it has backwards compatibility where you can pick if you want to use UA View ID or GA4 ID depending on project.

import {
  useGoogleLogin
} from '@react-oauth/google';
import axios from "axios"
import React from "react";
import {
  useState
} from 'react';
import './formcss.css';








function App() {
  let reponseGlobal;
  const login = useGoogleLogin({
    onSuccess: async response => {
      try {
        console.log(response.access_token);
        const res = await axios.post(`https://content-analyticsdata.googleapis.com/v1beta/properties/307948141:runRealtimeReport?alt=json`,

          {

            "metrics": [{
              "name": "activeUsers"
            }]
          }, {
            headers: {
              "Authorization": `Bearer ${response.access_token}`
            }
          }
        )
        if (res.data.rows['0'].metricValues["0"].value == null) {
          res.data.rows['0'].metricValues["0"].value = 0
        }
        reponseGlobal = response

        setactiveUsers(res.data.rows['0'].metricValues["0"].value);
        setloggedin(true);
        const interval = setInterval(function() {
          fetch();
        }, 5000);

      } catch (err) {
        console.log(err)
      }
    },
    scope: 'https://www.googleapis.com/auth/analytics.readonly'
  });





  async function fetch() {
    try {

      const res = await axios.post(`https://content-analyticsdata.googleapis.com/v1beta/properties/${gaID}:runRealtimeReport?alt=json`,

        {

          "metrics": [{
            "name": "activeUsers"
          }]
        }, {
          headers: {
            "Authorization": `Bearer ${reponseGlobal.access_token}`
          }
        }
      )
      if (res.data.rows['0'].metricValues["0"].value == null) {
        res.data.rows['0'].metricValues["0"].value = 0
      }
      setactiveUsers(res.data.rows['0'].metricValues["0"].value);
      console.log(res.data.rows['0'].metricValues["0"].value)
    } catch (err) {
      console.log("something died")
    }
  }



  const [gaID, setgaId] = useState('')
  const [activeUsers, setactiveUsers] = useState('')
  const [name, setName] = useState('')
  const [loggedin, setloggedin] = useState('')

  return (

    <
    div className = "form" >

    {!loggedin &&

      <
      div className = "Appheader" >
      <
      input
      placeholder = 'GA4 ID'
      name = "gaID"
      type = "gaID"
      onChange = {
        event => setgaId(event.target.value)
      }
      value = {
        gaID
      }
      className = "inputFields"

      /
      >
      <
      input
      placeholder = 'Project Name (any)'
      name = "name"
      type = "name"
      onChange = {
        event => setName(event.target.value)
      }
      value = {
        name
      }
      className = "inputFields"

      /
      >
      <
      button id = 'submit'
      onClick = {
        login
      } >
      Continue with google <
      /button>

      <
      /div>

    } {
      loggedin &&
        <
        div id = 'results' >
        <
        p > {
          name
        } < /p>

        <
        p id = 'total' > {
          activeUsers
        } < /p> < /
      div >
    } <
    /div>
  );
};
export default App;
.form {
  border-radius: 20px;
  background-color: thistle;
  width: 310px;
  height: 358px;
  background: rgba(0, 0, 0, 0.5);
}

input {
  font-size: 25px;
  padding: 5px;
  width: 100%;
}

.Appheader {
  display: flex;
  justify-content: center;
  flex-direction: column;
  padding: 30px;
  align-items: center;
}

#submit {
  font-size: large;
  border-radius: 20px;
  width: 90%;
  margin-top: 150px;
  height: 40px;
  border-width: 3px;
  border-style: groove;
  color: white;
  background-color: rgba(0, 0, 0, 0);
}

.inputFields {
  text-align: center;
  width: 90%;
  margin-top: 10px;
  border-radius: 20px;
  color: white;
  background-color: rgba(0, 0, 0, 0);
  border-width: 5px;
  border-style: groove;
}

::placeholder {
  text-align: center;
}

#results {
  color: white;
  display: flex;
  flex-direction: column;
  align-items: center;
  font-size: 15px;
}

#total {
  font-size: 80px;
}

h1 {
  font-size: 20px;
  margin-bottom: 20px;
}

p {
  font-size: 20px;
}

@media (min-width: 1200px) {
  .weather-side {
    left: 0px;
  }
  .container {
    width: 100%;
  }
  .form {
    width: 100%;
    margin-top: 20px;
  }
  .Appheader {
    padding: 10px;
  }
}

For the full app and any further concerns regarding the use case or idk anything else? Checkout my github I just wish this existed already so that I didn't had to go through all the hell of figuring it out, but it was still a lot of fun regardless not having the answers already coded out in someway for form that I just need to modify slightly to make them work with my project.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.