所以,首先,我要问这个问题,因为我希望有人承认或否认 - 对我来说是一个神话 - 即使用或不使用已弃用的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());
}
它有效,因为我可以看到数据。为什么秘密存在?这让我认为允许使用密钥,即使它已被弃用
任何意见?
所以我had this issue整整一年半,你是对的,使用Firebase和Apps脚本的信息已经过时且具有误导性。我想通了,我正在尝试更新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()
,它返回一个有效的“admin”或编辑级访问令牌,可以在Firebase调用中使用!我使用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
}
};
好吧,既然有些用户已经对问题进行了一年多的考虑(也考虑了Chris W的回答),我使用GSApp
库发布了该方法,该库也没有数据库秘密:
MJ5317VIFJyKpi9HCkXOfS0MLm9v2IJHf
service_account
(或者您想要命名它),并在值字段中粘贴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)
。