Подтвердить что ты не робот

Правильный способ добавить маршрут друга в node.js и mongoose?

Я планирую создать маршрут, где пользователь может добавить другого пользователя в качестве своего друга, чтобы они могли общаться друг с другом, когда они друзья.

Итак, как только пользователь A отправил запрос пользователю B, Пользователь B получит живое уведомление о запросе через socket.io

Проблема в том, что я не мог придумать свое решение о том, как реализовать описанный выше сценарий, из того, что я знаю, я должен создать два маршрута GET и POST

Я использую mongoose для запроса базы данных, вставки, обновления и удаления

Здесь мой код

// GET route for getting the user information -- Simple route

router.get('/users/:facebook_name', function(req, res) {
  User.findOne(facebook_name, function(err, user) {
    if (!user) {
      res.json({message: "Couldn't find a user by that name"});
      return;
    } 
    res.json(user);
  });
});

// POST route for adding a friend 
router.post('/friendships/create/:facebook_name', ensureAuthenticated, function(req, res) {
  // What should i put in this route to make the adding a friend feature works?
  User.findOneAndUpdate(facebook_name, function(err, user) {  
    if (user) {
      res.json({message: "You already send a friend request to that person"});
      return;
    } 
    // Send a live notification to the other user
    socket.emit('sending request', {message: "added you as a friend"});
  }); 
});

user Код схемы - не совсем уверен в этом.

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var UserSchema = new Schema({

  friends: [{ type: Schema.Types.ObjectId, ref: 'User'}],
  facebook: {
    id: String,
    token: String,
    // email: String,
    displayName: String,
    photo: String
  }
});

// Should I even create this schema?
var FriendsRequest = new Schema({

  madeBy: [{ type: Schema.Types.ObjectId, ref: 'User'}],


})

module.exports = mongoose.model('User', UserSchema);
module.exports = mongoose.model('FriendsRequest', FriendsRequest);

Я не совсем честен с вами, ребята, в маршруте POST, у меня нет лишней идеи о том, как писать логику, потому что я действительно запутался прямо сейчас, как пользователь B получит живой запрос уведомление? Должен ли я создать для этого еще один маршрут?

Это моя проблема, когда дело доходит до создания немного сложных приложений, я просто не мог придумать хорошую логику о том, как сделать определенную функцию, даже если она выглядит довольно легко. Я застрял в этой проблеме почти 4 часа, просматривая и читая сеть, но я считаю, что SO - единственное место, где я могу найти ключ к тому, как что-то сделать.

Спасибо.

4b9b3361

Ответ 1

Что вы можете сделать, так это создать сокет для каждого facebookName (если он уникален).

На стороне клиента:

socket.on('connection', function (data) {
   socket.emit('setFacebookName', facebookName); });
}

Сервер сохраняет каждый сокет с помощью facebookName:

socket.on('setFacebookName', function (facebookName) {
    users[facebookName]=socket;
});

Теперь, когда пользователь отправляет запрос чата этому пользователю в этот запрос

// POST route for adding a friend 
router.post('/friendships/create/:facebook_name', ensureAuthenticated, function(req, res) {
  // What should i put in this route to make the adding a friend feature works?
  User.findOneAndUpdate(facebook_name, function(err, user) {  
    if (user) {
      res.json({message: "You already send a friend request to that person"});
      return;
    } 
    // Send a live notification to the other user
    sendLiveNotification(facebook_name);
  }); 
});

function sendLiveNotification(facebookName){
   socket.on('send notification', function (facebookName) {
     users[facebookName].emit('sending request', "has sent friend request");
   });
}

Ответ 2

Вы пытаетесь получить двухэтапный процесс, поэтому вам потребуется как минимум два вызова, если один из запросов от запрашивающего, а другой - решение о том, разрешать или нет этот запрос у запрашивающего. Вы можете обработать свой обратный вызов для первой функции с использованием логического типа, где, если это новый запрос, пользователю может быть предложено всплывающее окно на клиенте.

Хорошая цель Mongoose - это расширения к Схеме, которые вы можете сделать, поэтому я добавляю две функции: одну из реквестера, запрашивающего дружбу-запросчика, а другую решение запрашивающего

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var UserSchema = new Schema({

  friendsAccepted: [{ type: Schema.Types.ObjectId, ref: 'User'}],
  friendsRequested: [{ type: Schema.Types.ObjectId, ref: 'User'}],
  friendsPending: [{ type: Schema.Types.ObjectId, ref: 'User'}],
  friendsRejected: [{ type: Schema.Types.ObjectId, ref: 'User'}],
  facebook: {
    id: String,
    token: String,
    // email: String,
    displayName: String,
    photo: String
  }
});



UserSchema.statics.requesterInitiatedRequestForFriendship = function(requesterID, requesteeID, cb) {
    mongoose.model('UserSchema').findOne({_id: requesterID}).exec(function(err, requester) {
        if (err) return cb(err);
        mongoose.model('UserSchema').findOne({_id: requesteeID}).exec(function(err, requestee) {
            if (err) return cb(err);
            if (requestee.friendsAccepted(requesterID) === -1 &&
                requestee.friendsRequested(requesterID) === -1 &&
                requestee.friendsPending(requesterID) === -1 &&
                requestee.friendsRejected(requesterID) === -1) {
                requestee.friendsPending.push(requesterID);
                requester.friendsRequested.push(requesterID);
                requestee.save();
                requester.save();
                cb(null, true);
            } else {
                cb(null, false);
            };
        });
    });
};

UserSchema.statics.requesteeDecidedOnFriendship = function(requesterID, requesteeID, allowed, cb) {
    mongoose.model('UserSchema').findOne({_id: requesterID}).exec(function(err, requester) {
        if (err) return cb(err);
        mongoose.model('UserSchema').findOne({_id: requesteeID}).exec(function(err, requestee) {
            if (err) return cb(err);
            if ((requestee.friendsAccepted(requesterID) === -1 &&
                requestee.friendsRequested(requesterID) === -1 &&
                requestee.friendsPending(requesterID) > -1 &&
                requestee.friendsRejected(requesterID) === -1) &&
                requester.friendsRequested(requesteeID) > -1) {
                requestee.friendsPending.forEach(function(uid, idx) {
                    if (uid === requesterID) {
                        requestee.friendsPending.splice(idx, 1);
                        return;
                    };
                });
                requester.friendsRequested.forEach(function(uid, idx) {
                    if (uid === requesteeID) {
                        requester.friendsRequested.splice(idx, 1);
                        return;
                    };
                });
                if (allowed) {
                    requestee.friendsAccepted.push(requesterID);
                    requester.friendsAccepted.push(requesteeID);
                } else {
                    requestee.friendsRejected.push(requesterID);
                    requester.friendsRejected.push(requesteeID);
                }
                requestee.save();
                requester.save();
            };
            cb(null);
        });
    });
}


module.exports = mongoose.model('User', UserSchema);

Итак, происходит несколько вещей:

  • не был протестирован
  • это не сухая
  • он ограничен без дополнительной схемы Дружбы

С помощью схемы дружбы вы можете определить уровни отклонения (например, "не в это время" и т.д.), вы можете более аккуратно очистить детали и гранулировать управление для изменения поведения дружбы. В вышесказанном вы можете видеть, что, как только вы отвергаетесь, это довольно фаталистично, поскольку он ни при каких обстоятельствах не станет подружиться! Поэтому, чтобы получить больше такого типа поведения, я определенно поеду с помощью схемы дружбы, в которой статики и методы будут очищены, как и пользователи.