如何在单个事务中在Firebase上创建用户和上载数据

时间:2017-03-26 11:24:17

标签: android firebase react-native firebase-realtime-database firebase-authentication

我正在创建一个Web应用程序,使用电子邮件和密码 firebase.auth()在Firebase上创建用户.createUserUsingEmailAndPassowrd()

创建帐户后,我会立即根据firebase数据库中的表单值上传一些数据。

一切正常,但有时候,在最坏的情况下,会创建用户,但由于网络问题,数据不会上传。该应用程序已经重定向到需要该数据并且整个应用程序失败的地方。

如果我尝试在数据库上传的数据也得到更新,我怎么能确定创建用户帐户呢?

摘要:确保在创建用户的同时上传某些数据,或者根本不创建用户。

4 个答案:

答案 0 :(得分:3)

firebaser here

目前Firebase中没有跨功能交易。常见的方法是:

  • 通过仔细订购代码来降低交叉功能问题的风险
  • 提高代码对跨功能失败的弹性

这意味着您决定哪一个更重要:每个现有用户都有一个数据库节点,每个数据库节点都指向一个现有用户。你似乎想回答“两个”,但正如所说:那是不可能的,你必须选择。在大多数情况下,我见过开发人员会选择选项1:每个Firebase身份验证用户必须在数据库中有一个节点。

在这种情况下,您需要在使用Firebase身份验证实际注册用户之前运行在数据库中注册用户的代码。并且由于用户只有在注册Auth后才能获得他们的UID,所以这里需要一些两步过程。所有非常讨厌的代码肯定会有问题。这就是为什么你会发现生产中的应用程序的大多数开发人员对这种方法的关注程度远低于你的想法。

相反,他们依赖于定期清理数据库。他们run an administrative process每天都会为用户扫描数据库,而无需相应的Firebase身份验证注册。这可以通过一个相当简单的过程处理各种边缘情况,甚至是与注册无关的边缘情况。您甚至可能将此称为“最终一致性”:最终数据库中的数据将与注册用户匹配。

对原始问题的最后评论:通过在Cloud Function for Firebase中运行注册和写入数据库代码,可以大大降低跨功能失败的可能性。在云功能中使用Admin SDK使这一切变得美观整洁。但是虽然失败的可能性减少很多,但 仍然会失败。因此,如果您关心数据的清洁度,您仍然需要清理过程。

答案 1 :(得分:1)

您可以在createUserUsingEmailAndPassowrd()的OnComplete方法中执行此操作。

mAuth.createUserWithEmailAndPassword(email, password)
        .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {

              if (task.isSuccessful()) {
                   //Create your user in DB here

                }
            }
        });

答案 2 :(得分:1)

因为您非常害怕最坏的情况(这是绝对正常的),所以这是一种方法:考虑您有以下字段:电子邮件,密码和地址。地址字段是您需要存储在数据库中的字段(当然还有用户uid)。

首先,您尝试注册用户,就像Faizy said一样,您使用onCompleteListener这样

mAuth.createUserWithEmailAndPassword(email, password)
    .onCompleteListener(... {
        ... onComplete (... task) {
            if (task.isSuccessful()) {
                doInsertTheData();
            }
...

当任务成功时,您希望将数据插入到数据库中,为{/ p>创建doInsertTheData()

private void doInsertTheData() {
     // I believe you familiar with Firebase database inserting method, so I skip the long part
     FirebaseDatabase...setValue(address, new CompletionListener() {
         ... onComplete(FirebaseError firebaseError, ...) {
             if (firebaseError == null) {
                 // if your code reach here, its a happy ending
             } else {
                 // if it reach here, then you can remove the signed in user
                 // and tell the user that their registration is failed and should try again
                 FirebaseAuth.getInstance().getCurrentUser().delete();
             }

然后,只要数据库保存过程失败,用户凭证就会被删除

  

注意:当我输入此内容时,我实际上还有另一种方法,但它太复杂了,我觉得这个方法更容易理解(尽管我还没试过/使用它)

答案 3 :(得分:0)

如果您需要用户使用某些数据来使用应用,那么他们登录时可能需要经常检查..

firebase.auth().onAuthStateChanged(user => {
  if (user) {
    // ... access ref to userData field(s) you care about..
    someUserFieldRef.once('value').then(snap => {
      if (! snap.exists()) {
        // redirect to setup page to add missing data..
      }
    })

  }
})

如果他们可以使用应用的其他部分,那么您可以推迟检查特定用户数据的时间,获取currentUser,然后检查数据..