gpt4 book ai didi

javascript - 范围问题 : storing account credentials in a new class object within a promise, 但现在需要在类的其余部分使用此对象

转载 作者:行者123 更新时间:2023-11-30 13:53:06 24 4
gpt4 key购买 nike

我已成功从 Firebase 检索数据以设置为客户端 ID 和客户端密码。为此,我必须使用 promise.then 以确保设置的凭据在检索数据后发生。

const SpotifyWebApi = require('spotify-web-api-node');
admin.firestore().collection('credentials').get().then((snapshot) => {
snapshot.docs.forEach(doc => {
console.log(JSON.stringify(doc.data().client_id));
// Credentials.client_id = JSON.stringify(doc.data().client_id);
console.log(JSON.stringify(doc.data().client_secret));
// Credentials.client_secret = JSON.stringify(doc.data().client_secret);
let client_id = JSON.stringify(doc.data().client_id);
let client_secret = JSON.stringify(doc.data().client_secret);
const credentials = new Credentials(regexIdAndSecret(client_id), regexIdAndSecret(client_secret));




const Spotify = new SpotifyWebApi({
client_id: credentials.client_id,
client_secret: credentials.client_secret,
redirectUri: `https://${process.env.GCLOUD_PROJECT}.firebaseapp.com/popup.html`
});
console.log('This is the client id after it has been set ' + credentials.client_id);
console.log('This is the client secret after it has been set ' + credentials.client_secret);

});


});

但是,我现在遇到了需要在其余代码中使用“Spotify”的困境。因为它在这个 promise 中,所以它的范围仅限于 promise 内部。如何使用正确检索的 Firebase 数据设置凭据,以便“Spotify”对象适用于整个类(class)?

我在下面使用 Spotify 对象的另一个地方的示例(但现在不工作,因为 Spotify 不再是类对象:

/**
* Redirects the User to the Spotify authentication consent screen. Also the 'state' cookie is set for later state
* verification.
*/
exports.redirect = functions.https.onRequest((req, res) => {

cookieParser()(req, res, () => {

const state = req.cookies.state || crypto.randomBytes(20).toString('hex');
console.log('Setting verification state:', state);
res.cookie('state', state.toString(), {maxAge: 3600000, secure: true, httpOnly: true});
const authorizeURL = Spotify.createAuthorizeURL(OAUTH_SCOPES, state.toString());
res.redirect(authorizeURL);
});
});

整个文件:

/**
* Main class holding all the logic which matches the Google assistant application to the Firebase database
* and the Spotify dashboard application. The application is formatted to reflect these three main parts with
* response-requests to Spotify for authorisation and to make api function calls (within the dialogflow fulfillment
* code towards the bottom of the class).
* Author: Marcus Watts
* Date Created: 01 July 2019
*/
'use strict';


/**
* --------------------------- Google/Dialogflow/Firebase Setup ---------------------------
* @type {{analytics; auth; crashlytics; database; firestore; https; pubsub; remoteConfig; storage; testLab; app: apps.Apps; Event: Event; EventContext: EventContext; Change: Change; ChangeJson: ChangeJson; Resource: Resource; TriggerAnnotated: TriggerAnnotated; Runnable: Runnable; HttpsFunction: HttpsFunction; CloudFunction: CloudFunction; MakeCloudFunctionArgs: MakeCloudFunctionArgs; makeCloudFunction; optionsToTrigger; config; firebaseConfig; region; runWith; FunctionBuilder: FunctionBuilder; SUPPORTED_REGIONS: readonly; MIN_TIMEOUT_SECONDS: number; MAX_TIMEOUT_SECONDS: number; VALID_MEMORY_OPTIONS: readonly; ScheduleRetryConfig: ScheduleRetryConfig; Schedule: Schedule; RuntimeOptions: RuntimeOptions; DeploymentOptions: DeploymentOptions}}
*/

// Modules being used
const functions = require('firebase-functions');
// Sets this file as the webhook for dialogflow filfillment
const {WebhookClient} = require('dialogflow-fulfillment');
// Used for storing the sign in data of the Spotify user
const cookieParser = require('cookie-parser');
const crypto = require('crypto');

// Firebase Setup
const admin = require('firebase-admin');
const serviceAccount = require('./service-account.json');
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: `https://${process.env.GCLOUD_PROJECT}.firebaseio.com`
});

// async function getCredentials() {
// const snapshot = await admin.firestore().collection('credentials').get();
// return snapshot;
// }
//


class Credentials {

constructor(client_id, client_secret) {
this.client_id = client_id;
console.log('Id in class ' + this.client_id);
this.client_secret = client_secret;
console.log('Secret in class ' + this.client_secret);

}


}

/**
* ----------------------Below section of code found at: LINK TO GIT REPOSTITORY---------------------------------
*/

function regexIdAndSecret(clientIdOrSecret){
const regex = /[(\w)]+/g;
let n;
let match;
while ((n = regex.exec(clientIdOrSecret)) !== null) {
// This is necessary to avoid infinite loops with zero-width matches
if (n.index === regex.lastIndex) {
regex.lastIndex++;
}

// The result can be accessed through the `n`-variable.
n.forEach((match, groupIndex) => {
return match;
console.log(`Found match, group ${groupIndex}: ${match}`);

});
console.log(`Found n, ${n}`);
return n;
}

}


// Spotify OAuth 2 setup
const SpotifyWebApi = require('spotify-web-api-node');
admin.firestore().collection('credentials').get().then((snapshot) => {
snapshot.docs.forEach(doc => {
console.log(JSON.stringify(doc.data().client_id));
// Credentials.client_id = JSON.stringify(doc.data().client_id);
console.log(JSON.stringify(doc.data().client_secret));
// Credentials.client_secret = JSON.stringify(doc.data().client_secret);
let client_id = JSON.stringify(doc.data().client_id);
let client_secret = JSON.stringify(doc.data().client_secret);
const credentials = new Credentials(regexIdAndSecret(client_id), regexIdAndSecret(client_secret));




const Spotify = new SpotifyWebApi({
client_id: credentials.client_id,
client_secret: credentials.client_secret,
redirectUri: `https://${process.env.GCLOUD_PROJECT}.firebaseapp.com/popup.html`
});
console.log('This is the client id after it has been set ' + credentials.client_id);
console.log('This is the client secret after it has been set ' + credentials.client_secret);

});

// Scopes to request. (Added in all the possible scopes for the auth so that it is possible to do any action that the
// Spotify api will allow i.e maximum permissions granted)
const OAUTH_SCOPES = [
'user-read-email',
'app-remote-control',
'streaming',
'user-modify-playback-state',
'playlist-read-private',
'user-library-modify',
'playlist-read-collaborative',
'playlist-modify-private',
'user-follow-modify',
'user-read-currently-playing',
'user-read-email',
'user-library-read',
'user-top-read',
'playlist-modify-public',
'user-follow-read',
'user-read-playback-state',
'user-read-recently-played'
];

/**
* Redirects the User to the Spotify authentication consent screen. Also the 'state' cookie is set for later state
* verification.
*/
exports.redirect = functions.https.onRequest((req, res) => {

cookieParser()(req, res, () => {

const state = req.cookies.state || crypto.randomBytes(20).toString('hex');
console.log('Setting verification state:', state);
res.cookie('state', state.toString(), {maxAge: 3600000, secure: true, httpOnly: true});
const authorizeURL = Spotify.createAuthorizeURL(OAUTH_SCOPES, state.toString());
res.redirect(authorizeURL);
});
});


/**
* Exchanges a given Spotify auth code passed in the 'code' URL query parameter for a Firebase auth token.
* The request also needs to specify a 'state' query parameter which will be checked against the 'state' cookie.
* The Firebase custom auth token is sent back in a JSONP callback function with function name defined by the
* 'callback' query parameter.
*/
exports.token = functions.https.onRequest((req, res) => {
try {
cookieParser()(req, res, () => {
console.log('Received verification state:', req.cookies.state);
console.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');
}
console.log('Received auth code:', req.query.code);
Spotify.authorizationCodeGrant(req.query.code, (error, data) => {
if (error) {
throw error;
}
/**
* Store the codes retained from the Authorization. (Added in the refresh token so that it can be used and set as appropriate to ensure
* the user is constantly connected to the Spotify api)
*/
console.log('Received Access Token:', data.body['access_token']);
console.log('Received Refresh Token:', data.body['refresh_token']);
Spotify.setAccessToken(data.body['access_token']);
Spotify.setRefreshToken(data.body['refresh_token']);
// setterForRefreshToken(data.body['refresh_token']);
Spotify.getMe(async (error, userResults) => {
if (error) {
throw error;
}
console.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) {
return res.jsonp({error: error.toString});
}
return null;
});

/**
* Creates a Firebase account with the given user profile and returns a custom auth token allowing
* signing-in this account.
* Also saves the accessToken to the datastore at /spotifyAccessToken/$uid
*
* @returns {Promise<string>} The Firebase custom auth token in a promise.
*/
async function createFirebaseAccount(spotifyID, displayName, photoURL, email, accessToken) {
// The UID we'll assign to the user.
const uid = `spotify:${spotifyID}`;

// Save the access token to the Firebase Realtime Database.
const databaseTask = admin.database().ref(`/spotifyAccessToken/${uid}`).set(accessToken);

// Create or update the user account.
const userCreationTask = admin
.auth()
.updateUser(uid, {
displayName: displayName,
photoURL: photoURL,
email: email,
emailVerified: true
})
.catch((error) => {
// If user does not exists we create it.
if (error.code === 'auth/user-not-found') {
return admin.auth().createUser({
uid: uid,
displayName: displayName,
photoURL: photoURL,
email: email,
emailVerified: true
});
}
throw error;
});

// Wait for all async tasks to complete, then generate and return a custom auth token.
await Promise.all([userCreationTask, databaseTask]);
// Create a Firebase custom auth token.
const token = await admin.auth().createCustomToken(uid);
console.log('Created Custom token for UID "', uid, '" Token:', token);
return token;
}

/**
* ----------------- Classes for storing the refresh and access tokens which are attained at sign in:-----------------
* used to create instance variables which can be accessible anywhere within the class
*/

class Refresh {
// Instance variables store the refresh token
constructor(refresh_token) {
this.refresh_token = refresh_token;
}
}

// Instance variables store the refresh token
class Access {
constructor(accessToken) {
this.accessToken = accessToken;
}
}


/**
* ---------------------------Setter and Getter Functions for Spotify Auth URL--------------------------------
*/

function setterForUpdatedAccessToken(splitString) {
Access.accessToken = splitString;
console.log('This is the access token being set in setterForUpdatedAccessToken', Access.accessToken);
}

function getterForUpdatedAccessToken() {
console.log('This is the access token being get in getterForUpdatedAccessToken', Access.accessToken);
return JSON.stringify(Access.accessToken);
}

更新:获取错误 Cannopt read property 'createAuthorizeURL' of undefined at spotify.then.Spotify

const spotify = admin.firestore().collection('credentials').get().then((snapshot) => {
snapshot.docs.forEach(doc => {
console.log(JSON.stringify(doc.data().client_id));
// Credentials.client_id = JSON.stringify(doc.data().client_id);
console.log(JSON.stringify(doc.data().client_secret));
// Credentials.client_secret = JSON.stringify(doc.data().client_secret);
let client_id = JSON.stringify(doc.data().client_id);
let client_secret = JSON.stringify(doc.data().client_secret);
const credentials = new Credentials(regexIdAndSecret(client_id), regexIdAndSecret(client_secret));


const Spotify = new SpotifyWebApi({
client_id: credentials.client_id,
client_secret: credentials.client_secret,
redirectUri: `https://${process.env.GCLOUD_PROJECT}.firebaseapp.com/popup.html`
});
console.log('This is the client id after it has been set ' + credentials.client_id);
console.log('This is the client secret after it has been set ' + credentials.client_secret);
return Spotify;
});



});

exports.redirect = functions.https.onRequest((req, res) => {

cookieParser()(req, res, () => {

const state = req.cookies.state || crypto.randomBytes(20).toString('hex');
console.log('Setting verification state:', state);
res.cookie('state', state.toString(), {maxAge: 3600000, secure: true, httpOnly: true});
spotify.then(Spotify => {
const authorizeURL = Spotify.createAuthorizeURL(OAUTH_SCOPES, state.toString());
res.redirect(authorizeURL);
});
});
});

最佳答案

从您的 .then 回调返回 spotify 类实例,并将 promise 存储在您所有其他代码可访问的某个地方。例如。在文件顶部或在单独的模块中:

// spotify.js
module.exports = admin.firestore().collection('credentials').get().then((snapshot) => {
/*...*/
return Spotify;
});

您可以在代码中的任何其他地方

const spotify = require('./spotify');
// ...
spotify.then(Spotify => {
// do stuff with Spotify
});

当然,如果您在异步函数中,您可以只使用 await(但我会选择不同的变量名称):

const Spotify = await spotify;
// do stuff with Spotify

例如:

const spotify = require('./spotify');
// ...
exports.redirect = functions.https.onRequest((req, res) => {

cookieParser()(req, res, () => {

const state = req.cookies.state || crypto.randomBytes(20).toString('hex');
console.log('Setting verification state:', state);
res.cookie('state', state.toString(), {maxAge: 3600000, secure: true, httpOnly: true});
spotify.then(Spotify => {
const authorizeURL = Spotify.createAuthorizeURL(OAUTH_SCOPES, state.toString());
res.redirect(authorizeURL);
});
});
});

关于javascript - 范围问题 : storing account credentials in a new class object within a promise, 但现在需要在类的其余部分使用此对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57840709/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com