范围问题:将帐户凭据存储在promise中的新类对象中,但现在需要在其余类中使用此对象

Marcooz2007

我已成功从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”。因为它在此承诺内,所以它的范围仅限于该承诺内。如何使用正确检索的Firebase数据设置凭据,以使“ Spotify”对象适用于整个类?

另一个地方的示例我在下面使用了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);
}

更新:出现错误,无法在spotify.then.Spotify读取未定义的读取属性'createAuthorizeURL'

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);
        });
    });
});

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

需要在java中使用父类的父对象来转换类对象

来自分类Dev

在类中创建新对象的问题

来自分类Dev

将对象数组存储在其自己的类C ++中

来自分类Dev

在其他模块中使用测试范围中的类

来自分类Java

从Java中的ArrayList中删除在其他类中使用的对象

来自分类Dev

存储类中的对象列表

来自分类Dev

在Matlab中B类的属性中使用A类的对象?

来自分类Dev

为什么需要在其元类派生自ABCMeta的类中使用@abstractmethod?

来自分类Java

如何在其他类中使用方法而不创建新对象

来自分类Dev

为什么要在变量中存储Promise对象?

来自分类Dev

C#如何使用存储在构造函数变量中的类名创建新对象?

来自分类Dev

使用ES6类的React Component中的此对象

来自分类Dev

将光标位置存储在类对象中(ncurses C ++)

来自分类Dev

C ++将包含多态属性的类对象存储在堆栈中

来自分类Java

从Person类将多个Address对象存储到TreeSet中

来自分类Dev

Django模型-接口设计避免需要在PARENT类中定义的CHILD类调用方法中传递对象

来自分类Dev

使用鼻子和python时TestCase类中的对象范围

来自分类Dev

根据用户选择从类模板中定义对象并解决本地定义对象的范围-新问题

来自分类Dev

c ++在函数中创建对象数组需要在全局范围内使用该数组

来自分类Dev

在Matlab中,如何使对象可在其类中访问?

来自分类Dev

在类中存储对对象的const引用

来自分类Dev

如何存储并访问ArrayList中的类对象?

来自分类Dev

我是否需要在实体框架6中使用POCO类

来自分类Dev

在提取器中,unapply方法是否需要在对象中或者应该在类中?

来自分类Dev

在Python中创建的类的对象问题

来自分类Dev

如何将类数据存储在数组中,并根据需要重新调用此数据?

来自分类Java

需要在Java类中使用此方法(科特琳)

来自分类Dev

python中的对象类类型是在其内部定义的吗?

来自分类Java

如何在其父类中处理@Autowire对象?

Related 相关文章

  1. 1

    需要在java中使用父类的父对象来转换类对象

  2. 2

    在类中创建新对象的问题

  3. 3

    将对象数组存储在其自己的类C ++中

  4. 4

    在其他模块中使用测试范围中的类

  5. 5

    从Java中的ArrayList中删除在其他类中使用的对象

  6. 6

    存储类中的对象列表

  7. 7

    在Matlab中B类的属性中使用A类的对象?

  8. 8

    为什么需要在其元类派生自ABCMeta的类中使用@abstractmethod?

  9. 9

    如何在其他类中使用方法而不创建新对象

  10. 10

    为什么要在变量中存储Promise对象?

  11. 11

    C#如何使用存储在构造函数变量中的类名创建新对象?

  12. 12

    使用ES6类的React Component中的此对象

  13. 13

    将光标位置存储在类对象中(ncurses C ++)

  14. 14

    C ++将包含多态属性的类对象存储在堆栈中

  15. 15

    从Person类将多个Address对象存储到TreeSet中

  16. 16

    Django模型-接口设计避免需要在PARENT类中定义的CHILD类调用方法中传递对象

  17. 17

    使用鼻子和python时TestCase类中的对象范围

  18. 18

    根据用户选择从类模板中定义对象并解决本地定义对象的范围-新问题

  19. 19

    c ++在函数中创建对象数组需要在全局范围内使用该数组

  20. 20

    在Matlab中,如何使对象可在其类中访问?

  21. 21

    在类中存储对对象的const引用

  22. 22

    如何存储并访问ArrayList中的类对象?

  23. 23

    我是否需要在实体框架6中使用POCO类

  24. 24

    在提取器中,unapply方法是否需要在对象中或者应该在类中?

  25. 25

    在Python中创建的类的对象问题

  26. 26

    如何将类数据存储在数组中,并根据需要重新调用此数据?

  27. 27

    需要在Java类中使用此方法(科特琳)

  28. 28

    python中的对象类类型是在其内部定义的吗?

  29. 29

    如何在其父类中处理@Autowire对象?

热门标签

归档