I've been working with the Firebase Admin SDK for Nodejs in the cloud functions to create custom auth tokens using Spotify and Firebase auth.
I've been trying to use the example given by Google that goes as follows:
exports.token = functions.https.onRequest((req, res) => {
try {
cookieParser()(req, res, () => {
functions.logger.log('Received verification state:', req.cookies.state);
functions.logger.log('Received state:', req.query.state);
if (!req.cookies.state) {
throw new Error('State cookie not set or expired. Maybe you took too long to authorize. Please try again.');
} else if (req.cookies.state !== req.query.state) {
throw new Error('State validation failed');
}
functions.logger.log('Received auth code:', req.query.code);
Spotify.authorizationCodeGrant(req.query.code, (error, data) => {
if (error) {
throw error;
}
functions.logger.log(
'Received Access Token:',
data.body['access_token']
);
Spotify.setAccessToken(data.body['access_token']);
Spotify.getMe(async (error, userResults) => {
if (error) {
throw error;
}
functions.logger.log(
'Auth code exchange result received:',
userResults
);
// We have a Spotify access token and the user identity now.
const accessToken = data.body['access_token'];
const spotifyUserID = userResults.body['id'];
const profilePic = userResults.body['images'][0]['url'];
const userName = userResults.body['display_name'];
const email = userResults.body['email'];
// Create a Firebase account and get the Custom Auth Token.
const firebaseToken = await createFirebaseAccount(spotifyUserID, userName, profilePic, email, accessToken);
// Serve an HTML page that signs the user in and updates the user profile.
res.jsonp({token: firebaseToken});
});
});
});
} catch (error) {
res.jsonp({error: error.toString()});
}
return null;
});
Here's the code from the client for making the request
const loginError = ref(null)
const route = useRoute()
console.log(route.query)
const { code, state, error } = route.query
function tokenReceived(data) {
if (data.token) {
projectAuth.signInWithCustomToken(data.token).then((userCredential) => {
console.log(userCredential)
})
} else {
console.error(data)
document.body.innerText = 'Error in the token Function: ' + data.error
}
}
if (error) {
loginError.value = 'Error back from the Spotify auth page: ' + error
} else if (code) {
// Use JSONP to load the 'token' Firebase Function to exchange the auth code against a Firebase custom token.
const script = document.createElement('script')
script.type = 'text/javascript'
// This is the URL to the HTTP triggered 'token' Firebase Function.
// See https://firebase.google.com/docs/functions.
const tokenFunctionURL =
'http://localhost:5001/pacelist-main/us-central1/token'
script.src =
tokenFunctionURL +
'?code=' +
encodeURIComponent(code) +
'&state=' +
encodeURIComponent(state) +
'&callback=' +
tokenReceived.name
document.head.appendChild(script)
}
const signIn = () => {
// Start the auth flow.
window.location.href =
'http://localhost:5001/pacelist-main/us-central1/redirect'
}
return { loginError, signIn }
Full repository here: https://github.com/firebase/functions-samples/tree/main/spotify-auth
But the jsonp callback doesn't seem to run when it goes back to my site. It should "Serve an HTML page that signs the user in and updates the user profile." and log the user in, but it does nothing. Been stuck on this one for days...