2017-03-16 53 views
1

我们有一个订购系统,最终用户可以通过他们的iOS应用订购餐饮。每个iOS应用都属于一个品牌,每个用户也属于一个品牌。我们将所有品牌信息放在一个Firebase项目中。数据库结构是:管理多租户应用的Firebase用户

-brands 
-- brand_id_1: 
    -- information 
-- brand_id_2: 
    -- information 

-stores 
-- store_id_1: 
    -- brand_id:brand_id_1 
    -- more information 
-- store_id_2: 
    -- brand_id:brand_id_1 
    -- more information 
-orders 
--brand_id_1: 
    --order_id_1: 
    --orderinfo 

--brand_id_2: 
    --order_id_4: 
    --orderinfo 

-users 
    -- user_id_1: 
    -- brand_id:brand_id_1 
    -- userinfo 
    -- user_id_2: 
    -- brand_id:brand_id_2 
    -- userinfo 

我们中的每个应用使用Facebook和Twitter的认证标志。但是,一个Firebase项目只能分配一个Facebook应用程序ID。这意味着如果用户下载brand1应用并通过Facebook登录,当他或她下载brand2应用时,该用户帐户将被创建,并且我们的用户会感到困惑。我们希望每个品牌都有自己的用户数据库,但我们仍然可以管理所有品牌并将数据存储在一个Firebase项目中。

我们想要做的是将所有品牌和商店放在主Firebase项目中,然后为每个品牌只为每个iOS应用创建一个Firebase项目。这些Firebase项目仅供用户登录(注册成功时,将uid放到主Firebase项目中),所有用户订单都将保存到我们的主要Firebase项目中。

这可能吗?或者其他更好的解决方案?

回答

0

每当你需要一个独立的应用程序用户时,你需要一个新的应用程序项目。按照this article中的说明,您可以按照项目使用多个数据库(适用于Android,但对于iOS类似 - ,您必须为每个要使用的项目在客户端初始化新的Firebase应用程序)。

+0

是的,我之前看过这篇文章,但这意味着如果我有100个品牌,我必须创建100个Firebase项目,并且每个项目仅供用户登录。此方法的缺点是什么? – Tim

+0

我想你只是说缺点!通常要求Firebase提供程序化项目创建,并且您可以投你一票:https://firebase.google.com/support/contact/bugs-features/ –

1

经过几个小时的学习,我想出了其他方法。这个想法是:

  1. 使用Facebook iOS SDK从iOS应用程序登录并获取Facebook令牌。
  2. iOS应用程序将此令牌发送到云功能,使用Graph api获取用户配置文件,然后从Facebook uid创建自定义令牌。
  3. 将此自定义令牌发送回iOS应用程序。
  4. iOS应用使用此令牌登录到Firebase。

的iOS代码:

func loginButton(_ loginButton: FBSDKLoginButton!, didCompleteWith result: FBSDKLoginManagerLoginResult!, error: Error!) { 
     if let token = result.token { 
      print(token.userID) 
      print(token.appID) 
      signInuser(with: token) 
     } 
    } 

func signInuser(with token:FBSDKAccessToken) { 
     Alamofire.request("https://xxx.cloudfunctions.net/verifyFacebookUser", method: .post, parameters: ["token":token.tokenString]).responseJSON(completionHandler: { (response) in 
      switch response.result { 
      case .success(let data): 
       if let json = data as? [String:String] { 
        FIRAuth.auth()?.signIn(withCustomToken: json["token"]!, completion: { (user, err) in 
         if let error = err { 
          print(error) 
         }else { 
          print(user!.displayName) 
          print(user!.email) 
         } 
        }) 
       } 


      case .failure(let error): 
       print(error) 
      } 
     }) 

    } 

云功能:

const functions = require('firebase-functions'); 
const admin = require('firebase-admin'); 
const graph = require('fbgraph'); 

var serviceAccount = require("./serviceAccountKey.json"); 

admin.initializeApp({ 
    credential: admin.credential.cert(serviceAccount), 
    databaseURL: "https://xxx.firebaseio.com" 
}); 

exports.verifyFacebookUser = functions.https.onRequest((req,res) => { 
    if (!req.body.token) { 
    return res.status(400).send('Access Token not found'); 
    } 

    graph.setAccessToken(req.body.token); 
    graph.get("me?fields=id,name,email", function(err, result) { 
    const firebaseUid = "fb:"+result.id; 
    admin.auth().createUser({ 
     uid:firebaseUid, 
     displayName:result.name, 
     email:result.email 
    }).then(function(userRecord){ 
     console.log(userRecord) 
     admin.auth().createCustomToken(userRecord.uid) 
     .then(function(customToken) { 
      res.send({token:customToken}); 
     }) 
     .catch(function(error) { 
      console.log("Error creating custom token:", error); 
     }) 
    }); 

    }); 
}); 

使用这种方法,每个品牌的iOS应用会要求用户同意从Facebook即使登录他或她已经从不同的品牌应用登录。但是这意味着iOS应用需要实施Firebase SDK已经提供的Facebook本地登录过程。

+1

通过这种方法,您还必须实施Twitter自己登录。 –

+0

你说得对。如果我可以为Firebase项目中的每个应用设置Facebook应用ID,我认为这会很好。 – Tim

+0

自定义令牌如何与Firebase身份验证一起使用? – Ayyappa