0

このFirebaseを初めて使用しているため、この技術を理解するのが難しいです。だから私はこのFirebase私のAndroidアプリケーションのデータを格納するために使用しています。このアプリケーションには、ユーザーがログインして顧客を作成するためのオプションが含まれています。そのアイデアは、ログインしたユーザーに基づいて顧客の詳細を追加、編集、および一覧表示することです。以下は、私が独自に追加したルールです。ログインしたユーザのFirebaseマッピング - 許可されていないエラー

{ 
    "rules": { 
    "users": { 
     "$UID": { 
     ".read": "auth.uid == $UID", 
     ".write": "auth.uid == $UID" 
     } 
    }, 
    "customers":{ 
     "$UID":{ 
     ".read": "auth.uid == $UID", //to make sure that only proper customer gets displayed and updated/added 
     ".write": "auth.uid == $UID", 

     "$CID":{ 

     "UserId":{ 
      ".validate": "(data.exists() && data.val() == newData.val()) || newData.val() == auth.uid" 
     }, 
     "CustomerName":{ 
      ".validate": "newData.isString() && newData.val().length < 100" 
     }, 
     "CustomerCode":{ 
      ".validate": "newData.isString() && newData.val().length<4" 
     }, 
     "CustomerLimit":{} 
     } 
     } 
    } 
    } 
}​ 

ここではアプリケーションのログイン部分です。

​auth.signInWithEmailAndPassword(email,password) 
.addOnCompleteListener(LoginActivity.this, new OnCompleteListener<AuthResult>() { 
    @Override 
    public void onComplete(@NonNull Task<AuthResult> task) { 
     ViewDialog.hideLoading(); 
     if(!task.isSuccessful()){ 
      Toast.makeText(LoginActivity.this,"Authentication failed",Toast.LENGTH_LONG).show(); 
     }else{ 
      Toast.makeText(LoginActivity.this,"Authentication success",Toast.LENGTH_LONG).show(); 
      Intent intent=new Intent(LoginActivity.this,HomeActivity.class); 
      finish(); 
      startActivity(intent); 
     } 

    } 
}); 

これは正常にログインします。ここで私は顧客を追加しようとしています。

​public class AddCustomer extends AppCompatActivity { 

    MaterialEditText editTextCustName,editTextCustCode,editTextCustLimit; 
    private DatabaseReference mFirebaseDatabase; 
    private FirebaseDatabase mFirebaseInstance; 
    private String customerId; 
    FloatingActionButton fabSaveUpdate; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_add_customer); 
     editTextCustName=(MaterialEditText) findViewById(R.id.txtCustName); 
     editTextCustCode=(MaterialEditText) findViewById(R.id.txtCustCode); 
     editTextCustLimit=(MaterialEditText) findViewById(R.id.txtCustLimit); 
     fabSaveUpdate=(FloatingActionButton) findViewById(R.id.btnCreateUpdateCustomer); 
     fabSaveUpdate.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       String customerName=editTextCustName.getText().toString().trim(); 
       String customerCode=editTextCustCode.getText().toString().trim(); 
       Double customerLimit=TextUtils.isEmpty(editTextCustLimit.getText().toString())?0d:Double.parseDouble(editTextCustLimit.getText().toString().trim()); 
       mFirebaseInstance = FirebaseDatabase.getInstance(); 
       mFirebaseInstance.setPersistenceEnabled(true); 
       // get reference to 'customers' node 
       mFirebaseDatabase = mFirebaseInstance.getReference("customers"); 
       Customer customer=new Customer(customerName,customerCode,customerLimit,FirebaseAuth.getInstance().getCurrentUser().getUid()); 
       createUser(customer); 
      } 
     }); 
    } 

    /** 
    * Creating new user node under 'users' 
    */ 
    private void createUser(final Customer customer) { 
     if (TextUtils.isEmpty(customerId)) { 
      customerId = mFirebaseDatabase.push().getKey(); 
     } 
     mFirebaseDatabase.child(customerId).setValue(customer); 
     //addUserChangeListener(); 
    } 

    /** 
    * User data change listener 
    */ 
    private void addUserChangeListener() { 
     mFirebaseDatabase.child(customerId).addValueEventListener(new ValueEventListener() { 
      @Override 
      public void onDataChange(DataSnapshot dataSnapshot) { 
       Customer customer = dataSnapshot.getValue(Customer.class); 

       Log.e(TAG, "Customer data is changed!" + customer.getCustomerName() + ", " + customer.getCustomerCode()); 

      } 

      @Override 
      public void onCancelled(DatabaseError error) { 
       // Failed to read value 
       Log.e(TAG, "Failed to read user", error.toException()); 
      } 
     }); 
    } 
} 

Customer.java

public class Customer 
{ 

    private String CustomerName; 
    private String CustomerCode; 
    private Double CustomerLimit; 
    private String UserId; //to store reference to current logged in user 
    public Customer(String custName,String custCode, Double custLimit, String userId){ 
     this.CustomerName=custName; 
     this.CustomerCode=custCode; 
     this.CustomerLimit=custLimit; 
     this.UserId=userId; 
    } 
    //getter and setters ommitted. 
} 

しかし、私はいつも、私は、ログイン後に新しい顧客を追加しようとするたびPERMISSION DENIEDを得続けます。私はそれがとwriteのオプションがRuleに設定されていることを知っていますが、私はここで何かを逃しています。追加する前にここで行う必要がある承認パートはありますか?私の前提ではログインは、それ以上の操作を許可するのに十分であった。間違っていれば私を訂正してください。

答えて

2

あなたの問題の説明とコードが参照に行くときに、第2の思想に...多分あなただけ.child(currentUserUid)を逃しました"ユーザー"と "顧客"がありますが、違いがあるかどうかは不明です。コードはCustomerをデータベースの/ customersの下に追加しますが、メソッド名はcreateUser()で、コメントには次のように書かれています。'users'の下に新しいユーザーノードを作成。/usersと/ customersの両方のセキュリティルールがあります。 /ユーザーのルールが必要または使用されているかどうかは不明です。

顧客が本当に単なるユーザーである場合、Rohitは答えとして、push()を使用してキーを生成するのではなく、UIDをキーとして顧客を保管するとします。

投稿されたコードが失敗するのは、path/customerのルールがないためです。ログインユーザーへのアクセスを制限する迅速な修正を行うには、以下のようにルールを更新してください。

{ 
    "rules": { 
    "users": { 
     "$UID": { 
     ".read": "auth.uid == $UID", 
     ".write": "auth.uid == $UID" 
     } 
    }, 
    "customers":{ 
     ".read": "auth != null", //ADD THIS 
     ".write": "auth != null", //ADD THIS 
     "$UID":{ // I don't understand what this is for. Needed? 
     ".read": "auth.uid == $UID", //to make sure that only proper customer gets displayed and updated/added 
     ".write": "auth.uid == $UID", 

     "$CID":{ 
     "UserId":{ 
      ".validate": "(data.exists() && data.val() == newData.val()) || newData.val() == auth.uid" 
     }, 
     "CustomerName":{ 
      ".validate": "newData.isString() && newData.val().length < 100" 
     }, 
     "CustomerCode":{ 
      ".validate": "newData.isString() && newData.val().length<4" 
     }, 
     "CustomerLimit":{} 
     } 
     } 
    } 
    } 
} 
+0

詳細をお寄せいただきありがとうございます。現在、ユーザーは値をキー入力してdbに直接登録しており、アプリケーションによる外部オプションはありません。ユーザーが作成されると、顧客を作成することができ、顧客は現在ログインしているユーザーとマッピングする必要があります。それは目的全体です。あなたのコメントごとに** //これが何であるか分かりません。私はこの背後にある論理を完全に理解していないので、間違った仮定かもしれません。私は読んでいると思っていて、顧客の書き込みは、ログインしたユーザーが有効なときにのみ行われます。 –

+0

..この操作を行います。間違っていたら訂正してください..これらの素晴らしいチュートリアルはありましたか?要件のタイプまたは同様のもの、同じものを共有していただけますか? –

+0

@GuruprasadRao:私が見つけたセキュリティルールの最も完全な説明は、この[documentation](httpsのさまざまなセクションです)には、これまでに見たことがあります。 ://firebase.google.com/docs/database/security/)。重要な概念の1つは、権限(ツリーをカスケード)(https://firebase.google.com/docs/database/security/securing-data#read_and_write_rules_cascade)です。 –

1

auth.uidのUIDは、Firebase Authが使用するために与えられる特別なIDです。 push().getKey()によって生成されたキーは、タイムスタンプされたユニークキーで、auth.uidと同じではありません。

Firebaseによって生成されたUIDを使用して、自分のIDの代わりに顧客データを直接保存できると思います。あなたは

currentUserUid = FirebaseAuth.getInstance().getCurrentUser().getUid() 

EDITを使用して、現在のユーザーのUIDを取得することができます:あなたは、「顧客」ノード

関連する問題