채팅방에서 사용자를 추적하고보고하려고하는데 Firebase에서 데이터를 가장 잘 구성하는 방법을 잘 모르겠습니다.
json을 반환하는 API에 액세스 할 수 있습니다. 1 분마다 API를 폴링하여 모든 채팅방 (room_id)을 찾은 다음 각 방의 모든 사용자 (user_id)를 요청할 계획입니다.
데이터 설정은 전적으로 우리가 제어합니다.
아니요,하지만 문서에 언급 된대로 Firebase.ServerValue.TIMESTAMP를 사용할 수 있습니다 . Firebase는 사용자가 저장하도록 요청한 내용 만 저장합니다.
가능한 경우 모든 날짜 시간에 Firebase.ServerValue.TIMESTAMP (Unix Epoch)를 사용합니다. 이것은 new Date().getTime()
로컬 머신의 시간에 의존하는 다른 방법을 사용 하거나 비교할 때 일관성과 정확성을 보장합니다 (종종 잘못되어 데이터가 엉망이 될 것입니다).
유닉스 신기원는 특히 우리가 사용할 수 있습니다, 또한 작동하는 정수 아주 잘와 중포 기지의 질의 능력있는 .startAt()
과 .endAt()
(우리는이 질문에 대해 아래 참조 겠지만) 특정 날짜 범위에서 사물을 가져올 수 있습니다.
첫 번째 질문은 "이 데이터를 어떻게 사용합니까?"입니다. Firebase는 구조를 바로 확보 한 다음 복잡한 쿼리에 의존하여 실수를 보완 할 수있는 큰 SQL 데이터베이스가 아닙니다.
Firebase에서 구조를 빌드 할 때 특정 방식으로 데이터를로드 할 수 있는지 확인하세요 . 즉 room_id
, 데이터를로드 할 의 목록이 있다는 것을 알고 있다면 방 구조가 해당 ID를 기반으로해야합니다.
간단한 대화방에 대해 이와 같은 구조를 고려하십시오 ( $
표기법을 사용 하여 와일드 카드를 나타냄).
{
"rooms": {
$room_id: {
"users": {
$user_id: true
},
"_meta": {
closed: Boolean
},
"messages": {
$message_id: {
"user_id": $user_id,
"text": ""
}
}
}
},
"users": {
$user_id: {...}
}
}
의 ID와 사용자가 때 abe
기호가있는 방 조인 room_id
의를 room_one
, 우리는 그들이 위치를 설정하여 채팅방의 회원으로 자신을 표시해야합니다 알고 /rooms/room_one/users/abe
에를 true
.
방에 참여하는 우리의 기능은 다음과 같습니다.
function joinRoom(room_id) {
// We assume `ref` is a Firebase reference to the root of our Firebase
var roomRef = ref.child("rooms").child(room_id);
roomRef.child("users").child(myUserId).set(true);
return roomRef;
}
이것은 구체적입니다. 몇 가지 정보가 제공되고 데이터 구조가 논리적이기 때문에 Firebase에서 데이터를로드하지 않고도 어떤 데이터를 작성해야하는지 쉽게 가정 할 수 있습니다.
하지만보고를 원하기 때문에 이것은 귀하의 상황에 충분하지 않습니다. 귀하의 필요에 따라 점진적으로 구조를 개선 할 것입니다.
방별로 이야기한다고 가정하면 이것은 쉬운 변화입니다.
{
"rooms": {
$room_id: {
"users": {
$user_id: true
},
"users_history": {
$push_id: {
user_id: ...,
timestamp: ...
}
},
"messages": {
$message_id: {...}
}
}
},
"users": {
$user_id: {...}
}
}
/users/$room_id/users_history
위치를 추가합니다 . 사용자가이 방에 들어갈 때마다 목록입니다. 약간의 복잡성을 추가 했으므로 객실 참여 기능은 다음과 같습니다.
function joinRoom(room_id) {
var roomRef = ref.child("rooms").child(room_id);
roomRef.child("users_history").push({
user_id: myUserId,
timestamp: Firebase.ServerValue.TIMESTAMP
});
roomRef.child("users").child(myUserId).set(true);
return roomRef;
}
이제 Firebase Query를 사용하여 주어진 시간에 방에 있었던 사용자 수를 쉽게보고 할 수 있습니다 .
function roomVisitors(room_id, start_datetime, end_datetime) {
var roomRef = ref.child("rooms").child(room_id),
queriedRoomRef = roomRef
.orderByChild('timestamp')
.startAt(start_datetime.getTime())
.endAt(end_datetime.getTime());
// Assuming we use some ES6 promise library
return new Promise(function (resolve, reject) {
queriedRoomRef.once("value", function (users) {
/* Users will be a snapshot of all people who
came into the room for the given range of time. */
resolve(users.val());
}, function (err) {
reject(err);;
});
});
}
이 작업이 진정으로 "특정"한지 잠시 후에 이야기 할 것이지만 이것이 일반적인 아이디어입니다.
/users/$user_id
아직 구조를 구체화 하지는 않았지만 여기서해야합니다. 이 상황에서 사용자의 온라인 사용 시간을 조회해야하는 유일한 정보는 user_id
. 그래서 우리는이 정보를 아래에 /user/$user_id
저장해야 /rooms/
할 것입니다. 왜냐하면 우리가 그것을 아래에 저장한다면 우리 는 모든 방에 대한 데이터를로드 하고 관련 사용자 정보를 찾기 위해 그것을 반복해야 할 것이고 그것은 매우 구체적이지 않기 때문입니다.
{
"rooms": {
$room_id: {
"users": {
$user_id: true
},
"users_history": {
$push_id: {
user_id: ...,
timestamp: ...
}
},
"messages": {
$message_id: {...}
}
}
},
"users": {
$user_id: {
"online_history": {
$push_id: {
"action": "", // "online" or "offline"
"timestamp": ...
}
}
}
}
}
이제 ref.onAuth(func)
온라인에서 시간을 추적하는를 구축 할 수 있습니다.
var userRef;
ref.onAuth(function (auth) {
if (!auth && userRef) {
// If we haven no auth, i.e. we log out, cancel any onDisconnect's
userRef.onDisconnect().cancel();
// and push a record saying the user went offline
userRef.child("online_history").push({
action: "offline",
timestamp: Firebase.ServerValue.TIMESTAMP
});
} else if (auth) {
userRef = ref.child('users').child(auth.uid);
// add a record that we went offline
userRef.child('online_history').push({
action: "online",
timestamp: Firebase.ServerValue.TIMESTAMP
});
// and if the user disconnects, add a record of going offline
userRef.child('online_history').push().onDisconnect().set({
action: "offline",
timestamp: Firebase.ServerValue.TIMESTAMP
});
}
});
이 방법을 사용하면 위에서 사용한 것과 동일한 쿼리 방법을 사용하여 온라인 / 오프라인 로그를 반복하고 주어진 범위에 대한 시간을 합산하는 함수를 작성할 수 있습니다.하지만이 방법은 독자를위한 연습으로 남겨 두겠습니다.
어떤보고 기능도 구체적이지 않습니다. 첫 번째 쿼리에서 방을 방문한 사용자 목록을 가져올 때 사용자 이름으로 채워진 큰 개체를 가져 와서 모든 데이터를 가져 와서 클라이언트 측에서 파싱합니다. 우리가 정말로 원하는 것이 정수일 때 순 방문자 수의 가치.
이것은 서버 측 SDK를 사용하여 NodeJS 작업자를 실제로 사용하려는 상황입니다. 이 작업자는 앉아서 데이터 구조의 변경 사항을 관찰 할 수 있으며 데이터가 변경되면 자동으로 요약하여 클라이언트가 다음과 같은 위치를보고 /rooms/$room_id/_meta/analytics/uniqueVisitorsThisWeek
단순히 10
.
요점은 스토리지가 저렴하고 이와 같은 데이터를 요약하고 캐싱하는 것이 저렴하지만 서버 측에서 수행되는 경우에만 가능하다는 것입니다. 구체적이지 않고 너무 많이로드하고 클라이언트 측 요약을 시도하면 CPU주기와 대역폭을 낭비하게됩니다.
Firebase에서 클라이언트로 데이터를로드하고 해당 데이터를 표시하지 않는 경우 데이터 구조를 더 구체적으로 수정해야합니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다