รับผู้ใช้ตามคุณสมบัติชื่อโดยใช้ Firebase


129

ฉันกำลังพยายามสร้างแอปพลิเคชันที่ฉันสามารถรับ / ตั้งค่าข้อมูลในบัญชีผู้ใช้ที่เฉพาะเจาะจงและฉันถูก Firebase ล่อลวง

ปัญหาที่ฉันพบคือฉันไม่รู้ว่าจะกำหนดเป้าหมายข้อมูลผู้ใช้เฉพาะอย่างไรเมื่อโครงสร้างของฉันมีลักษณะดังนี้:

โครงสร้างข้อมูลของฉันอธิบายตามข้อความด้านล่าง

online-b-cards
  - users
    - InnROTBVv6FznK81k3m
       - email: "hello@hello"
       - main:  "Hello world this is a text"
       - name:  "Alex"
       - phone: 12912912

ฉันมองไปรอบ ๆ แล้วและฉันไม่พบอะไรเลยเกี่ยวกับวิธีเข้าถึงข้อมูลแต่ละรายการนับประสาอะไรกับเมื่อพวกเขาได้รับแฮชแบบสุ่มเป็น ID ของพวกเขา

ฉันจะดึงข้อมูลผู้ใช้แต่ละรายตามชื่อของพวกเขาได้อย่างไร หากมีวิธีที่ดีกว่านี้โปรดบอกฉัน!


คำตอบ:


156

ก่อนหน้านี้ Firebase กำหนดให้คุณต้องสร้างดัชนีของคุณเองหรือดาวน์โหลดข้อมูลทั้งหมดในตำแหน่งที่ตั้งเพื่อค้นหาและดึงข้อมูลองค์ประกอบที่ตรงกับแอตทริบิวต์ย่อย (เช่นผู้ใช้ทั้งหมดที่มีname === "Alex")

ในเดือนตุลาคม 2014 Firebase ได้เปิดตัวฟังก์ชันการสืบค้นใหม่โดยใช้orderByChild()วิธีนี้ซึ่งช่วยให้คุณสามารถค้นหาประเภทนี้ได้อย่างรวดเร็วและมีประสิทธิภาพ ดูคำตอบที่อัปเดตด้านล่าง


เมื่อเขียนข้อมูลไปยัง Firebase คุณมีตัวเลือกที่แตกต่างกันเล็กน้อยซึ่งจะแสดงถึงกรณีการใช้งานที่แตกต่างกัน ในระดับสูง Firebase เป็นที่เก็บข้อมูล NoSQL ที่มีโครงสร้างแบบต้นไม้และมีพื้นฐานง่ายๆสำหรับจัดการรายการข้อมูล:

  1. เขียนถึง Firebase ด้วยคีย์ที่ไม่ซ้ำใครและเป็นที่รู้จัก:

    ref.child('users').child('123').set({ "first_name": "rob", "age": 28 })
    
  2. ต่อท้ายรายการด้วยคีย์ที่สร้างขึ้นโดยอัตโนมัติซึ่งจะจัดเรียงตามเวลาที่เขียนโดยอัตโนมัติ:

    ref.child('users').push({ "first_name": "rob", "age": 28 })
    
  3. รับฟังการเปลี่ยนแปลงข้อมูลตามเส้นทางที่ไม่ซ้ำใครและเป็นที่รู้จัก:

    ref.child('users').child('123').on('value', function(snapshot) { ... })
    
  4. กรองหรือจัดลำดับข้อมูลในรายการตามค่าคีย์หรือแอตทริบิวต์ :

    // Get the last 10 users, ordered by key
    ref.child('users').orderByKey().limitToLast(10).on('child_added', ...)
    
    // Get all users whose age is >= 25
    ref.child('users').orderByChild('age').startAt(25).on('child_added', ...)
    

นอกจากนี้orderByChild()คุณไม่จำเป็นต้องสร้างดัชนีของคุณเองสำหรับการสืบค้นเกี่ยวกับแอตทริบิวต์ย่อยอีกต่อไป! ตัวอย่างเช่นในการดึงข้อมูลผู้ใช้ทั้งหมดที่มีชื่อ "Alex":

ref.child('users').orderByChild('name').equalTo('Alex').on('child_added',  ...)

Engineer ที่ Firebase ที่นี่ เมื่อเขียนข้อมูลลงใน Firebase คุณมีตัวเลือกที่แตกต่างกันเล็กน้อยซึ่งจะแสดงกรณีการใช้งานแอปพลิเคชันที่แตกต่างกัน เนื่องจาก Firebase เป็นที่เก็บข้อมูล NoSQL คุณจึงต้องจัดเก็บออบเจ็กต์ข้อมูลของคุณด้วยคีย์ที่ไม่ซ้ำกันเพื่อให้คุณสามารถเข้าถึงรายการนั้นโดยตรงหรือโหลดข้อมูลทั้งหมดในตำแหน่งเฉพาะและวนซ้ำแต่ละรายการเพื่อค้นหาโหนดที่คุณต้องการ . ดูการเขียนข้อมูลและการจัดการรายการสำหรับข้อมูลเพิ่มเติม

เมื่อคุณเขียนข้อมูลใน Firebase คุณสามารถsetใช้ข้อมูลโดยใช้เส้นทางที่ไม่ซ้ำกัน (เช่นa/b/c) หรือpushข้อมูลลงในรายการซึ่งจะสร้างรหัสเฉพาะ (เช่นa/b/<unique-id>) และช่วยให้คุณสามารถจัดเรียงและสืบค้นข้อมูลในรายการนั้นตามเวลา . รหัสที่ไม่ซ้ำว่าคุณเห็นข้างต้นจะถูกสร้างขึ้นโดยการเรียกผนวกรายการไปยังรายการที่pushonline-b-cards/users

แทนที่จะใช้pushที่นี่ฉันขอแนะนำให้ใช้setและจัดเก็บข้อมูลสำหรับผู้ใช้แต่ละคนโดยใช้คีย์ที่ไม่ซ้ำกันเช่นที่อยู่อีเมลของผู้ใช้ จากนั้นคุณสามารถเข้าถึงข้อมูลของผู้ใช้ได้โดยตรงโดยไปที่online-b-cards/users/<email>ผ่าน Firebase JS SDK ตัวอย่างเช่น:

function escapeEmailAddress(email) {
  if (!email) return false

  // Replace '.' (not allowed in a Firebase key) with ',' (not allowed in an email address)
  email = email.toLowerCase();
  email = email.replace(/\./g, ',');
  return email;
}

var usersRef = new Firebase('https://online-b-cards.firebaseio.com/users');
var myUser = usersRef.child(escapeEmailAddress('hello@hello.com')) 
myUser.set({ email: 'hello@hello.com', name: 'Alex', phone: 12912912 });

โปรดทราบว่าเนื่องจาก Firebase ไม่อนุญาตให้ใช้อักขระบางตัวในการอ้างอิง (ดูการสร้างการอ้างอิง ) เราจึงลบ.และแทนที่ด้วย,โค้ดด้านบน


1
@RobDiMarco คุณมีคำตอบสำหรับคำถามที่ Stephen โพสต์ไว้ด้านล่างนี้หรือไม่?
Charles Han

2
เฮ้ @RobDiMarco แม้ว่าคำแนะนำของคุณในการใช้ที่อยู่อีเมลเป็นพื้นฐานสำหรับรหัสนั้นยังคงถูกต้องอยู่ แต่คุณควรขยายคำตอบเพื่อชี้ไปที่orderByChildคุณลักษณะใหม่ เนื่องจากคำตอบนี้มักปรากฏเป็นคำตอบที่เกี่ยวข้อง / เกี่ยวข้องผู้คนจึงต้องดูคำตอบนี้และควรทราบถึงคุณลักษณะการสืบค้นใหม่
Frank van Puffelen

1
@FrankvanPuffelen ความคิดที่ดี - ขอบคุณสำหรับบันทึก ฉันจะอัปเดตวันนี้
Rob DiMarco

1
@Ced น่าเสียดายที่ฉันไม่สามารถแสดงความคิดเห็นเกี่ยวกับสิ่งที่อยู่ในผลงานได้ ฉันสัญญาว่าเราทำงานหนัก (นั่นเป็นเรื่องจริงเสมอ) แต่ไม่สามารถระบุรายละเอียดได้ API ฐานข้อมูลมีข้อ จำกัด ในบางวิธีและเราตั้งใจที่จะเปิดเผยเฉพาะวิธีการที่เราสามารถรับประกันประสิทธิภาพได้ในระดับหนึ่ง นี่คือเหตุผลที่เราไม่เปิดเผยวิธีการเรียกใช้การดำเนินการในรายการทั้งหมดตัวอย่างเช่น ประเด็นที่เป็นธรรมสำหรับเอกสารสำหรับผู้ใช้ขั้นสูง หากมีข้อสงสัยลองใช้ Google Group ของเราเพื่อดูการสนทนาโดยละเอียด: groups.google.com/forum/#!forum/firebase-talkทีมมีความกระตือรือร้นที่นี่!
Rob DiMarco

1
@RobDiMarco ที่น่าฟัง เมื่อวานนี้ฉันเห็นฟังก์ชัน Firebase และรู้สึกตื่นเต้นตลอดทั้งวันเพราะฉันคิดว่า Firebase เป็นตัวเปลี่ยนเกมและกำลังจะปฏิวัติแบ็คเอนด์ อย่างจริงจังฉันสามารถสอนคนที่ไม่เคยเขียนโค้ดมาก่อนในชีวิตให้ดูแลแบ็กเอนด์ใน Firebase น่าทึ่งมากและน่ากลัวทีเดียว Cheers
Ced

5

คุณสามารถรับรายละเอียดโดยใช้รหัสต่อไปนี้

FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("users");
myRef.orderByChild("name").equalTo("Alex").addListenerForSingleValueEvent(new ValueEventListener() {           
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {

                    for (DataSnapshot childDataSnapshot : dataSnapshot.getChildren()) {
                        Log.d(TAG, "PARENT: "+ childDataSnapshot.getKey());
                        Log.d(TAG,""+ childDataSnapshot.child("name").getValue()); 
                    }

4

ฉันคิดว่าแนวทางที่ดีที่สุดคือการกำหนดรหัสของผู้ใช้ตามวัตถุรับรองความถูกต้องที่ Firebase จัดหาให้ เมื่อฉันสร้างผู้ใช้ของฉันฉันทำ:

FirebaseRef.child('users').child(id).set(userData);

รหัสนี้มาจาก:

var ref = new Firebase(FIREBASE);
var auth = $firebaseAuth(ref);
auth.$authWithOAuthPopup("facebook", {scope: permissions}).then(function(authData) {
    var userData = {}; //something that also comes from authData
    Auth.register(authData.uid, userData);
}, function(error) {
    alert(error);
});

บริการตรวจสอบสิทธิ์ของ Firebase จะตรวจสอบให้แน่ใจว่ามีการตั้งค่ารหัสที่ไม่ซ้ำกันของผู้ให้บริการทั้งหมดที่ uid ด้วยวิธีนี้คุณจะมี auth.uid และสามารถเข้าถึงผู้ใช้ที่ต้องการเพื่ออัปเดตได้อย่างง่ายดายเช่น:

FirebaseRef.child('users').child(id).child('name').set('Jon Snow');

2

นี่เป็นการถอดความโพสต์ที่ช่วยฉันเมื่อพยายามเข้าถึงรหัสเฉพาะที่สร้างขึ้นโดยอัตโนมัติ เข้าถึงรหัสเฉพาะของ Firebase ภายใน ng-repeat โดยใช้ angularFire implicit sync

ขอบคุณ bennlich (ที่มา):

Firebase ทำงานเหมือนวัตถุจาวาสคริปต์ทั่วไป บางทีตัวอย่างด้านล่างอาจทำให้คุณไปถูกทาง

<div ng-repeat="(name, user) in users">
    <a href="" ng-href="#/{{name}}">{{user.main}}</a>
</div>

แก้ไข: ไม่แน่ใจ 100% กับผลลัพธ์ที่คุณต้องการ แต่ต่อไปนี้เป็นข้อมูลเพิ่มเติมเล็กน้อยที่อาจจุดประกายช่วงเวลา 'aha' คลิกที่คีย์ที่คุณพยายามเข้าถึงในแดชบอร์ด Firebase ของคุณ จากตรงนั้นคุณสามารถใช้สิ่งต่างๆเช่น:

var ref = new Firebase("https://online-b-cards.firebaseio.com/users/<userId>/name);
    ref.once('value', function(snapshot) {
        $scope.variable= snapshot.val();
});

สวัสดี Anthony ขอบคุณสำหรับข้อมูลเกี่ยวกับโครงสร้าง REST (?) และแน่นอนว่ามันทำให้ 'aha' สะดุด เมื่อมองย้อนกลับไปที่โพสต์นี้มันชัดเจนสำหรับฉันตอนนี้ฉันได้จัดโครงสร้างข้อมูลของฉันด้วยวิธีที่ไม่สะดวกขอบคุณสำหรับเคล็ดลับและฉันจะจำไว้สำหรับโปรเจ็กต์ที่ใช้ firebase ครั้งต่อไปของฉัน!
Richard Bamford

2

นี่คือวิธีเข้าถึงคีย์เฉพาะที่สร้างขึ้นโดยอัตโนมัติใน Firebase: โครงสร้างข้อมูล : - OnlineBcards - UniqueKey

database.ref().on("value", function(snapshot) {
      // storing the snapshot.val() in a variable for convenience
      var sv = snapshot.val();
      console.log("sv " + sv); //returns [obj obj]

      // Getting an array of each key in the snapshot object
      var svArr = Object.keys(sv);
      console.log("svArr " + svArr); // [key1, key2, ..., keyn]
      // Console.log name of first key
      console.log(svArr[0].name);
}, function(errorObject) {
  console.log("Errors handled: " + errorObject.code);
});

1

วิธีที่ง่ายที่สุดคือหยุดใช้ไฟล์ .push(){}

ฟังก์ชันซึ่งจะสร้างคีย์สุ่มนั้น แต่ให้ใช้.update(){}ฟังก์ชันที่คุณสามารถระบุชื่อของเด็กแทนการมีคีย์สุ่ม


1

การดึงข้อมูล:

ในฐานข้อมูลของคุณคุณกำลังใช้ id สุ่มที่สร้างขึ้นโดยใช้push()ดังนั้นหากคุณต้องการดึงข้อมูลให้ทำดังต่อไปนี้:

การใช้ Firebase ในแอป Android:

DatabaseReference ref=FirebaseDatabase.getInstance().getReference().child("users");
ref.addListenerForSingleValueEvent(new ValueEventListener() {           
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {

                for (DataSnapshot datas : dataSnapshot.getChildren()) {
                    String name=datas.child("name").getValue().toString();
                }
             }

            @Override
           public void onCancelled(DatabaseError databaseError) {
          }
     });

การใช้ Firebase ใน Javascript:

  firebase.database().ref().child("users").on('value', function (snapshot) {
   snapshot.forEach(function(childSnapshot) {
    var name=childSnapshot.val().name;
  });
});

ที่นี่คุณมีสแนปชอต (ตำแหน่งของข้อมูล) usersจากนั้นคุณจะวนซ้ำภายในรหัสสุ่มทั้งหมดและดึงชื่อ


การดึงข้อมูลสำหรับผู้ใช้เฉพาะ:

ตอนนี้หากคุณต้องการดึงข้อมูลสำหรับผู้ใช้เฉพาะคุณต้องเพิ่มแบบสอบถาม:

การใช้ Firebase ในแอป Android:

DatabaseReference ref=FirebaseDatabase.getInstance().getReference().child("users");
Query queries=ref.orderByChild("name").equalTo("Alex");
queries.addListenerForSingleValueEvent(new ValueEventListener() {...}

การใช้ Firebase กับ Javascript

firebase.database().ref().child("users").orderByChild("name").equalTo("Alex").on('value', function (snapshot) {
   snapshot.forEach(function(childSnapshot) {
      var name=childSnapshot.val().name;
   });
});

การใช้orderByChild("name").equalTo("Alex")ก็เหมือนกับการพูดwhere name="Alex"เพื่อดึงข้อมูลที่เกี่ยวข้องกับอเล็กซ์


วิธีที่ดีที่สุด:

สิ่งที่ดีที่สุดคือการใช้ Firebase Authentication จึงสร้าง id เฉพาะสำหรับผู้ใช้แต่ละคนและใช้แทน id แบบสุ่มpush()วิธีนี้คุณไม่ต้องวนซ้ำผู้ใช้ทั้งหมดเนื่องจากคุณมี id และสามารถเข้าถึงได้ง่าย

ขั้นแรกผู้ใช้ต้องลงชื่อเข้าใช้จากนั้นคุณสามารถดึง ID เฉพาะและแนบ Listener เพื่อดึงข้อมูลอื่น ๆ ของผู้ใช้นั้น:

การใช้ Firebase กับ Android:

DatabaseReference ref = FirebaseDatabase.getInstance().getReference("users");
String uid = FirebaseAuthentication.getInstance().getCurrentUser().getUid();

ref.child(uid).addListenerForSingleValueEvent(new ValueEventListener() {
          @Override
         public void onDataChange(DataSnapshot dataSnapshot) { 
           String name=dataSnapshot.child("name").getValue().toString(); 
   }
         @Override
       public void onCancelled(DatabaseError databaseError) {
      }
 });

การใช้ Firebase กับ Javascript:

    var user = firebase.auth().currentUser;
    var uid=user.uid;

    firebase.database().ref().child("users").child(uid).on('value', function (snapshot) {
     var name=snapshot.val().name;
   });
 

0

วิธีที่ง่ายที่สุดและดีกว่าในการเพิ่ม Id เฉพาะไปยังฐานข้อมูล ur ตามผู้ใช้ที่ได้รับการพิสูจน์ตัวตนคือ:

private FirebaseAuth auth;

String UId=auth.getCurrentUser().getUid();

FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("Users");

User user = new User(name,email,phone,address,dob,bloodgroup);

myRef.child(UId).setValue(user);

UId จะเป็นรหัสเฉพาะสำหรับอีเมล / ผู้ใช้ที่มีการพิสูจน์ตัวตน


3
นั่นไม่ได้ตอบคำถาม คำถามคือวิธีรับและตั้งค่าข้อมูลในบัญชีผู้ใช้เฉพาะ รหัสของคุณสร้างบัญชีผู้ใช้และไม่ถูกต้องเนื่องจากคุณไม่สามารถ. setValue (ผู้ใช้) ได้เนื่องจากผู้ใช้ไม่ใช่พารามิเตอร์ที่ถูกต้อง
เจย์
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.