Skip to content

Instantly share code, notes, and snippets.

@timrijckaert
Last active September 14, 2023 08:43
Show Gist options
  • Save timrijckaert/218be90541a7285e21455fafa2962dea to your computer and use it in GitHub Desktop.
Save timrijckaert/218be90541a7285e21455fafa2962dea to your computer and use it in GitHub Desktop.
Fetch Firebase tokens for topic

Firebase Topic Counter

This little script will output the amount of tokens subscribed to a topic.
You will need to replace the variables with your personal ones in order for it to work.

We used this function in a Lambda which sends the results to a monitoring dashboard.

How to get the variables

Screenshots in the comments.

var sha1 = require('sha1');
var fetch = require('node-fetch');
//See README.md
var key = "key";
var projectId = "firebase project id;
//Check cookies from https://console.firebase.google.com
var SID = "sid";
var HSID = "hsid";
var SSID = "ssid";
var APISID = "apisid";
var SAPISID = "sapisid";
exports.handler = async(event) => {
const origin = "https://console.firebase.google.com";
const secretFromDevConsole = `https://gcmcontextualcampaign-pa.clients6.google.com/v1/4/projects/${projectId}/topics?prefix=/topics/&key=${key}`;
const generateAuthorizationHeader = () => {
const currentTime = new Date().getTime();
const sapisid = SAPISID;
const hashed = sha1(`${currentTime} ${sapisid} ${origin}`);
return `SAPISIDHASH ${currentTime}_${hashed}`;
};
const getTopicSubscriptionsCall = async() => {
const authorizationKey = generateAuthorizationHeader();
await fetch(secretFromDevConsole, {
method: "GET",
headers: {
"Authorization": authorizationKey,
"X-Origin": origin,
"cookie": `SID=${SID}; HSID=${HSID}; SSID=${SSID}; APISID=${APISID}; SAPISID=${SAPISID}`
},
})
.then(response => response.json())
.then(async json => {
const topics = json.topic;
topics.forEach(topic => console.log(topic.name + " " + topic.size));
return { statusCode: 200 };
});
};
await getTopicSubscriptionsCall();
};
{
"name": "check-firebase-breaking-topic-subscriptions",
"version": "1.0.0",
"description": "Check Firebase breaking topic subscription",
"main": "index.js",
"dependencies": {
"node-fetch": "^2.3.0",
"sha1": "^1.1.1"
},
"author": "Tim Rijckaert",
"license": "ISC"
}
@timrijckaert
Copy link
Author

Screenshot from 2019-05-17 00-12-14
Screenshot from 2019-05-17 00-13-50
Screenshot from 2019-05-17 00-14-27

Copy link

ghost commented Feb 8, 2023

Hi there @timrijckaert ,

Thank you for your work !

However the script is not working for me, I get stuck with response 403 : "The caller does not have permission".

When I change one of the cookie info or else, I found another issue (401 "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.") which let me think that the parameters I set are corrects.

I also try to add all information I could find from the original cookie header into your function, still stuck with 403.

Is this script still working for you ? Am I missing something ?
I use firebase backend functions in order to call the console api from a firebase env.

Thanks,
Orazio

@Jaluanda
Copy link

Hi there @timrijckaert ,

Thank you for your work !

However the script is not working for me, I get stuck with response 403 : "The caller does not have permission".

When I change one of the cookie info or else, I found another issue (401 "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.") which let me think that the parameters I set are corrects.

I also try to add all information I could find from the original cookie header into your function, still stuck with 403.

Is this script still working for you ? Am I missing something ? I use firebase backend functions in order to call the console api from a firebase env.

Thanks, Orazio

In my case I missing the "X-Goog-AuthUser" header, maybe because my browser session is using multiple accounts.

@Aulig
Copy link

Aulig commented Aug 13, 2023

I think it's broken these days without the __Secure-1**** cookies. Unfortunately __Secure-1PSIDTS expires very quickly (roughly 10 mins), so it's impractical to keep extracting the cookies.

Copy link

ghost commented Aug 18, 2023

Thank you @Jaluanda, your fixed worked perfectly 😊

@Aulig you're right.
How do you know only the __Secure-1.. is missing ? If see many info in the original cookie header, is there a way to gen all of them ? 😅

Here is the error triggered :
Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.

@Aulig
Copy link

Aulig commented Aug 18, 2023

Thank you @Jaluanda, your fixed worked perfectly 😊

@Aulig you're right. How do you know only the __Secure-1.. is missing ? If see many info in the original cookie header, is there a way to gen all of them ? 😅

Here is the error triggered : Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.

I tested it against some other Firebase endpoint. It works as long as you send the 3 cookies starting with __Secure-1. The __Secure-2*** and __Secure-3*** weren't necessary in my experiments (meaning it worked without them).

No idea how to generate __Secure-1PSIDTS since it frequently expires. Supposedly you can get a fresh one by calling accounts.google.com/RotateCookies but I couldn't figure out the correct way to use that endpoint. Would need to dig into the JS that calls this endpoint on the firebase website.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment