我目前正在开发一个涉及将卡上传到数据库的项目。我正在使用Swift 4并使用google的firebase作为数据库。我已经制作了代码功能,用于将手牌放到游戏区域,但是当它们从游戏区域的一个区块移动到另一个区块时,它会创建卡片的副本,而不是移动已经存在的卡片。仔细观察后我发现这是因为retrieveUpdates方法中的snapshot.ref没有检索数据库中已有卡的正确引用值。这导致它调用代码来创建一张新卡。
我的问题是:为什么snapshot.ref的值在它们被另一个使用和接收的时间之间发生变化?
//Sends a card and location to the database when a card is moved
func updateDatabase(playingCard: PlayingCard) {
let cardUpdate = Database.database().reference().child("Updates")
//This takes the location that the sender dropped the card.
if let location = game.location(from: playingCard.card) {
if case .battlefield(let field, let stack) = location {
//If the card is already in the database it should keep its old ID but if it is new it should be assigned a new ID
let reference = playingCard.databaseRef ?? cardUpdate.childByAutoId()
let updateDictionary = ["Sender": String(playerNumber),"Card": playingCard.card.name, "Field": String(field), "Stack": String(stack)]
if playingCard.databaseRef == nil {
playingCard.databaseRef = reference
reference.setValue(updateDictionary)
}
else {
reference.updateChildValues(updateDictionary)
}
}
}
}
func retrieveUpdates() {
let cardUpdate = Database.database().reference().child("Updates")
cardUpdate.observe(.childAdded) { (snapshot) in
if snapshot.childrenCount != 0 {
self.processUpdate(snapshot: snapshot)
}
}
cardUpdate.observe(.childChanged, with: { (snapshot) in
self.processUpdate(snapshot: snapshot)
})
}
func processUpdate(snapshot: DataSnapshot) {
let snapshotValue = snapshot.value as! Dictionary<String,String>
let cardName = snapshotValue["Card"]!
let sender = Int(snapshotValue["Sender"]!)
let stack = Int(snapshotValue["Stack"]!)
let relativeField = snapshotValue["Field"]!
if sender != self.playerNumber {
let fieldNumber = (4 + sender! - self.playerNumber + Int(relativeField)!) % 4
var foundCard = false
for playingCard in self.gameGraphics.cards.reversed() {
if let databaseRef = playingCard.databaseRef, databaseRef == snapshot.ref {
foundCard = true
self.currentPlayingCard = CurrentPlayingCard(playingCard: playingCard, startPosition: playingCard.position, touchPoint: playingCard.position, location: Location.dataExtract())
}
}
if foundCard == false {
let card = self.gameGraphics.addFromDatabase(name: cardName, field: fieldNumber, stack: stack!, scene: self)
card.databaseRef = snapshot.ref
self.currentPlayingCard = CurrentPlayingCard(playingCard: card, startPosition: card.position, touchPoint: card.position, location: Location.dataExtract())
}
self.touchUp(atPoint: self.gameGraphics.allBattlefields[fieldNumber][stack!].position)
}
}
非常感谢任何帮助。这是我用swift编写的第一个程序之一,所以我的编码实践仍然不是很好。
这是加载的场景。
override func sceneDidLoad() {
super.sceneDidLoad()
anchorPoint = CGPoint(x: 0, y: 1)
FirebaseApp.configure()
let login = loginInfo()
Auth.auth().signIn(withEmail: login.username, password: login.password) { (user, error) in
if error != nil {
print(error!)
} else {
print("login Successful")
}
}
retrieveUpdates()
}