所以,首先,我问的是这个问题,因为我希望有人承认或否认 - 对我来说是一个神话 - 关于使用或不使用 弃用firebase数据库机密。
为什么这样?好吧,在Firebase控制台的 服务帐户 标签中,我可以读到:
数据库机密目前已被弃用,并使用旧版Firebase令牌生成器。使用Firebase Admin SDK
更新源代码
但是在这个建议之下,我现在可以看到我的密钥。如果实际上不推荐使用这个密钥,为什么这可能呢?
但是这个故事并没有在这里结束。如果使用Google Apps脚本(even on officials)搜索教程,他们使用已弃用的数据库密钥,但您可以阅读:
Google警告不推荐使用此身份验证方法。实际上,您仍然可以使用此方法,但标准服务帐户更安全且值得推荐。由于数据库机密更容易使用,对于大多数用例而言,远非真正弃用和安全,这就是我们将在此处使用的内容。
再次,这怎么可能?
我想说我尝试过:
function myFunction() {
var firebaseUrl = "https://myApp.firebaseio.com/";
var secret = "theKey";
var database = FirebaseApp.getDatabaseByUrl(firebaseUrl, secret);
Logger.log(database.getData());
}
它有效,因为我可以看到数据。为什么秘密存在? 这让我认为允许使用密钥,即使它已被弃用
有什么意见吗?
答案 0 :(得分:1)
因此,我had this issue一年半后 ,您是正确的,在那里将Firebase与Apps Script一起使用的信息已经过时,误导。我发现了这个问题,并正在尝试更新StackOverflow和教程中的信息。
但是这个故事并没有到此结束。如果使用Google Apps脚本(even on officials)搜索教程,它们将使用不建议使用的数据库密钥,但是您可以阅读......
您在此处添加的此链接实际上是一个名为@RomainVialard的家伙实际上是第三方网站。过去,他的东西对我非常有用。虽然他网站上的教程已经过时,但他创建的库仍然运行良好,并且最近更新了。
问题(服务器端)- OP问题的答案
因此对于服务器端,我使用official-ish OAuth2 Library从service account with a private key:https://console.firebase.google.com/u/0/project/<YOUR-PROJECT-ID>/settings/serviceaccounts/adminsdk
生成访问令牌。然后,我创建了一个从oauth2库中检索令牌的函数:
function getFirebaseService() {
return OAuth2.createService('Firebase')
// Set the endpoint URL.
.setTokenUrl('https://accounts.google.com/o/oauth2/token')
// Set the private key and issuer. I stored mine in the PropertiesService... You could just use a variable somewhere.
.setPrivateKey(fb_PRIVATE_KEY) //Service account private key
.setIssuer(fb_SERVICE_EMAIL) //Service account email
// Set the property store where authorized tokens should be persisted.
.setPropertyStore(PropertiesService.getScriptProperties())
// Set the scopes.
.setScope('https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/firebase.database');
}
使用此代码,然后我可以调用getFirebaseService().getAccessToken()
,它返回可以在Firebase调用中使用的 valid 'admin'或 Editor级访问令牌 !我使用FirebaseApp库是因为它很容易!
var service = getFirebaseService();
if (service.hasAccess()) {
var fb = FirebaseApp.getDatabaseByUrl(fb_URL, service.getAccessToken());
//Success! Do what ever with Firebase!!
} else {
Logger.log("makeToken: " + service.getLastError());
}
如果需要,您还可以生成客户端身份验证令牌以使用客户端:FirebaseApp.getDatabaseByUrl(fb_URL, service.getAccessToken()).createAuthToken(USER_EMAIL);
。
另一个常见问题(客户端)
我必须克服的in my question主要问题是Firebase Admin SDK已升级到3.x。如果您 update the tutorial code to use the 3.x version ,一切正常!
// Initialize Firebase
var config = {
apiKey: "<Web API Key>",
authDomain: "<Project ID>.firebaseapp.com",
databaseURL: "https://<DB URL>.firebaseio.com/"
};
firebase.initializeApp(config);
//userRequestToken is retrieved from server-side Romain's FirebaseApp Library linked above.
firebase.auth().signInWithCustomToken(userRequestToken).catch(function(error) {
// Handle Errors here.
console.error("authClient: ", error.code, error.message);
});
return {
uid: firebase.auth().currentUser.uid,
metadata: {
lastSignInTime: firebase.auth().currentUser.lastSignInTime
}
};
答案 1 :(得分:1)
好吧,现在,有些用户对这个问题感兴趣-一年多以后-(还请考虑 Chris W 的回答),我使用GSApp
库发布方法,该方法也可以在没有 databse秘密 的情况下工作:
安装 GSApp 库。为此,请转到“资源”标签,然后单击“库”并粘贴库ID: MJ5317VIFJyKpi9HCkXOfS0MLm9v2IJHf
创建服务帐户:
复制下载的 JSON密钥文件的内容,并将其粘贴到您的脚本属性中。为此,请转到文件-> 项目属性-> 脚本属性选项卡。在 Property 字段中键入service_account
(或者您要为其命名),然后在 Value 字段中粘贴所有内容 JSON密钥文件。
使用以下代码作为示例:
function myFunction() {
var firebaseUrl = "https://YOUR-FIREBASE-PROJECT.firebaseio.com/";
var jsonKey = JSON.parse(PropertiesService.getScriptProperties().getProperty("service_account"));
var key = jsonKey.private_key;
var clientEmail = jsonKey.client_email;
var serverToken = new GSApp.init(key, ['https://www.googleapis.com/auth/firebase.database', 'https://www.googleapis.com/auth/userinfo.email'], clientEmail);
serverToken.addUser(clientEmail).requestToken();
var token = serverToken.getToken(clientEmail).token;
var dataPath = 'YOUR-FIREBASE-DATA-PATH';
var options = {};
var result = UrlFetchApp.fetch( firebaseUrl + dataPath + '.json' + '?access_token=' + token, options).getContentText();
var data = JSON.parse(result);
var keys = Object.keys(data);
var sheetRow = [];
var entryKeys;
for (index in keys) {
sheetRow = [];
entryKeys = Object.keys(data[keys[index]])
for (i in entryKeys) {
Logger.log(entryKeys[i]);
}
}
}
您从Firebase获得的数据是 json对象,这意味着您需要手动(forEach, map, for ... of)
浏览对象的所有属性。