יצירת מסד נתונים של Firestore באמצעות ספריית לקוח לאינטרנט או לנייד
במדריך המקוצר הזה מוסבר איך להגדיר את Firestore, להוסיף נתונים ולקרוא נתונים באמצעות ספריית הלקוח של Android, פלטפורמות Apple, Web, Unity או C++.
.אם עדיין לא עשיתם זאת, אתם צריכים ליצור פרויקט ב-Firebase: במסוף Firebase, לוחצים על הוספת פרויקט ופועלים לפי ההוראות שמופיעות במסך כדי ליצור פרויקט ב-Firebase או כדי להוסיף שירותי Firebase לפרויקט קיים. Google Cloud
בחלונית הימנית, עוברים אל Databases & Storage (מסדי נתונים ואחסון) > Firestore.
לוחצים על יצירת מסד נתונים.
בוחרים מיקום למסד הנתונים.
אם אי אפשר לבחור מיקום, סימן שהמיקום של משאבי ברירת המחדל Google Cloud בפרויקט כבר הוגדר. חלק מהמשאבים בפרויקט (כמו מופע ברירת המחדל של Firestore) חולקים תלות משותפת במיקום, ואפשר להגדיר את המיקום שלהם במהלך יצירת הפרויקט או כשמגדירים שירות אחר שחולק את התלות הזו במיקום.
בוחרים מצב התחלתי לכללי האבטחה של Firestore:
- מצב בדיקה
מתאים להתחלת העבודה עם ספריות לקוח לנייד ולאינטרנט, אבל מאפשר לכל אחד לקרוא ולשכתב את הנתונים. אחרי הבדיקה, חשוב לעיין בסעיף הגנה על הנתונים.
כדי להתחיל להשתמש ב-SDK לאתרים, לפלטפורמות של אפל או ל-Android SDK, בוחרים במצב בדיקה.
- מצב נעילה
ההרשאה הזו חוסמת את כל פעולות הקריאה והכתיבה מלקוחות ניידים ומלקוחות אינטרנט. שרתי האפליקציות המאומתים שלכם (C#, Go, Java, Node.js, PHP, Python או Ruby) עדיין יכולים לגשת למסד הנתונים.
כדי להתחיל להשתמש בספריית הלקוח של שרת C#, Go, Java, Node.js, PHP, Python או Ruby, בוחרים במצב נעול.
קבוצת הכללים הראשונית של כללי האבטחה ב-Firestore תחול על מסד הנתונים שמוגדר כברירת מחדל ב-Firestore. אם יוצרים כמה מסדי נתונים לפרויקט, אפשר לפרוס כללי אבטחה ב-Firestore לכל מסד נתונים.
לוחצים על יצירה.
כשמפעילים את Firestore, מערכת ה-API מופעלת גם בCloud API Manager.
הגדרת סביבת הפיתוח
מוסיפים לאפליקציה את התלויות הנדרשות ואת ספריות הלקוח.
גרסה 9 לאינטרנט
- פועלים לפי ההוראות להוספת Firebase לאפליקציית האינטרנט.
-
מייבאים גם את Firebase וגם את Firestore:
import { initializeApp } from "firebase/app"; import { getFirestore } from "firebase/firestore";
גרסה 8 לאינטרנט
- פועלים לפי ההוראות להוספת Firebase לאפליקציית האינטרנט.
- מוסיפים את ספריות Firebase ו-Firestore לאפליקציה:
חבילת Firestore SDK זמינה גם כחבילת npm. <script src="https://www.gstatic.com/firebasejs/8.10.1/firebase-app.js"></script> <script src="https://www.gstatic.com/firebasejs/8.10.1/firebase-firestore.js"></script>
תצטרכו להגדיר ידנית את הדרישות ל-Firebase ול-Firestore.npm install firebase@8.10.1 --save
const firebase = require("firebase"); // Required for side-effects require("firebase/firestore");
פלטפורמות של אפל
פועלים לפי ההוראות להוספת Firebase לאפליקציית Apple.
משתמשים ב-Swift Package Manager כדי להתקין ולנהל יחסי תלות ב-Firebase.
- ב-Xcode, כשהפרויקט של האפליקציה פתוח, עוברים אל File > Swift Packages > Add Package Dependency (קובץ > חבילות Swift > הוספת תלות בחבילה).
- כשמוצגת בקשה, מוסיפים את מאגר Firebase Apple platforms SDK:
- בוחרים את ספריית Firestore.
- אחרי שתסיימו, פלטפורמת Xcode תתחיל לטפל ביחסי התלות ולהוריד אותם ברקע באופן אוטומטי.
https://github.com/firebase/firebase-ios-sdk
Android
- פועלים לפי ההוראות להוספת Firebase לאפליקציית Android.
- מצהירים על התלות של ספריית Firestore ל-Android בקובץ Gradle של המודול (ברמת האפליקציה) (בדרך כלל
app/build.gradle.ktsאוapp/build.gradle):implementation("com.google.firebase:firebase-firestore:26.3.0")
אם האפליקציה שלכם משתמשת בכמה ספריות Firebase, כדאי להשתמש ב-Firebase Android BoM, כדי לוודא שגרסאות ספריות Firebase באפליקציה תמיד תואמות.
מחפשים מודול ספרייה ספציפי ל-Kotlin? החל מגרסת אוקטובר 2023, מפתחי Kotlin ומפתחי Java יכולים להסתמך על מודול הספרייה הראשי (פרטים נוספים זמינים במאמר שאלות נפוצות בנושא).
Dart
- אם עדיין לא עשיתם זאת, מגדירים את Firebase ומפעילים אותו באפליקציית Flutter.
- מהרמה הבסיסית (root) של פרויקט Flutter, מריצים את הפקודה הבאה כדי להתקין את הפלאגין:
flutter pub add cloud_firestore
- בסיום התהליך, צריך לבנות מחדש את אפליקציית Flutter:
flutter run
C++
- פועלים לפי ההוראות כדי להוסיף את Firebase לפרויקט C++.
- ממשק C++ ל-Android.
- תלויות של Gradle. מוסיפים את השורות הבאות לקובץ Gradle של המודול (ברמת האפליקציה) (בדרך כלל
app/build.gradle):android.defaultConfig.externalNativeBuild.cmake { arguments "-DFIREBASE_CPP_SDK_DIR=$gradle.firebase_cpp_sdk_dir" } apply from: "$gradle.firebase_cpp_sdk_dir/Android/firebase_dependencies.gradle" firebaseCpp.dependencies { // earlier entries auth firestore }
- תלויות בינאריות. באופן דומה, הדרך המומלצת לקבל את יחסי התלות הבינאריים היא להוסיף את הקוד הבא לקובץ
CMakeLists.txt:add_subdirectory(${FIREBASE_CPP_SDK_DIR} bin/ EXCLUDE_FROM_ALL) set(firebase_libs firebase_auth firebase_firestore firebase_app) # Replace the target name below with the actual name of your target, # for example, "native-lib". target_link_libraries(${YOUR_TARGET_NAME_HERE} "${firebase_libs}")
- כדי להגדיר שילוב של אפליקציות למחשב, אפשר לעיין במאמר איך מוסיפים את Firebase לפרויקט C++.
Unity
- פועלים לפי ההוראות להוספת Firebase לפרויקט Unity.
- משתמשים בממשק Unity כדי להגדיר את הפרויקט כך שיבצע מיניפיקציה של גרסאות build ל-Android.
- האפשרות נמצאת בPlayer Settings > Android > Publishing Settings > Minify.
- יכול להיות שהאפשרויות יהיו שונות בגרסאות שונות של Unity, לכן מומלץ לעיין במסמכי התיעוד הרשמיים של Unity ובמדריך לניפוי באגים ב-Firebase Unity Build.
-
אם אחרי הפעלת המיניפיקציה מספר השיטות שמופיעות בהפניה עדיין חורג מהמגבלה, אפשרות נוספת היא להפעיל את
multidexב:-
mainTemplate.gradleאם האפשרות Custom Gradle Template (תבנית Gradle מותאמת אישית) מופעלת בקטע Player Settings (הגדרות הנגן) -
או קובץ
build.gradleברמת המודול, אם משתמשים ב-Android Studio כדי לבנות את הפרויקט המיוצא.
-
כדי להימנע מההודעה Error while merging dex archives, צריך לכווץ את ה-build.
הפעלה של Firestore במצב Native
מאתחלים מופע של Firestore:
גרסה 9 לאינטרנט
// Initialize Firestore through Firebase import { initializeApp } from "firebase/app" import { getFirestore } from "firebase/firestore" const firebaseApp = initializeApp({ apiKey: '### FIREBASE API KEY ###', authDomain: '### FIREBASE AUTH DOMAIN ###', projectId: '### CLOUD FIRESTORE PROJECT ID ###' }); const db = getFirestore();
גרסה 8 לאינטרנט
// Initialize Firestore through Firebase firebase.initializeApp({ apiKey: '### FIREBASE API KEY ###', authDomain: '### FIREBASE AUTH DOMAIN ###', projectId: '### CLOUD FIRESTORE PROJECT ID ###' }); var db = firebase.firestore();
Swift
import FirebaseCore import FirebaseFirestore FirebaseApp.configure() let db = Firestore.firestore()
Objective-C
@import FirebaseCore; @import FirebaseFirestore; // Use Firebase library to configure APIs [FIRApp configure]; FIRFirestore *defaultFirestore = [FIRFirestore firestore];
Kotlin
Android
// Access a Firestore instance from your Activity val db = Firebase.firestore
Java
Android
// Access a Firestore instance from your Activity FirebaseFirestore db = FirebaseFirestore.getInstance();
Dart
db = FirebaseFirestore.instance;
C++
// Make sure the call to `Create()` happens some time before you call Firestore::GetInstance(). App::Create(); Firestore* db = Firestore::GetInstance();
Unity
using Firebase.Firestore; using Firebase.Extensions;
FirebaseFirestore db = FirebaseFirestore.DefaultInstance;
הוספת נתונים
נתונים ב-Firestore מאוחסנים במסמכים, שמאוחסנים באוספים. Firestore יוצר אוספים ומסמכים באופן מרומז בפעם הראשונה שמוסיפים נתונים למסמך. אתם לא צריכים ליצור אוספים או מסמכים באופן מפורש.
יוצרים אוסף ומסמך חדשים באמצעות קוד הדוגמה הבא.
גרסה 9 לאינטרנט
import { collection, addDoc } from "firebase/firestore"; try { const docRef = await addDoc(collection(db, "users"), { first: "Ada", last: "Lovelace", born: 1815 }); console.log("Document written with ID: ", docRef.id); } catch (e) { console.error("Error adding document: ", e); }
גרסה 8 לאינטרנט
db.collection("users").add({ first: "Ada", last: "Lovelace", born: 1815 }) .then((docRef) => { console.log("Document written with ID: ", docRef.id); }) .catch((error) => { console.error("Error adding document: ", error); });
Swift
// Add a new document with a generated ID do { let ref = try await db.collection("users").addDocument(data: [ "first": "Ada", "last": "Lovelace", "born": 1815 ]) print("Document added with ID: \(ref.documentID)") } catch { print("Error adding document: \(error)") }
Objective-C
// Add a new document with a generated ID __block FIRDocumentReference *ref = [[self.db collectionWithPath:@"users"] addDocumentWithData:@{ @"first": @"Ada", @"last": @"Lovelace", @"born": @1815 } completion:^(NSError * _Nullable error) { if (error != nil) { NSLog(@"Error adding document: %@", error); } else { NSLog(@"Document added with ID: %@", ref.documentID); } }];
Kotlin
Android
// Create a new user with a first and last name val user = hashMapOf( "first" to "Ada", "last" to "Lovelace", "born" to 1815, ) // Add a new document with a generated ID db.collection("users") .add(user) .addOnSuccessListener { documentReference -> Log.d(TAG, "DocumentSnapshot added with ID: ${documentReference.id}") } .addOnFailureListener { e -> Log.w(TAG, "Error adding document", e) }
Java
Android
// Create a new user with a first and last name Map<String, Object> user = new HashMap<>(); user.put("first", "Ada"); user.put("last", "Lovelace"); user.put("born", 1815); // Add a new document with a generated ID db.collection("users") .add(user) .addOnSuccessListener(new OnSuccessListener<DocumentReference>() { @Override public void onSuccess(DocumentReference documentReference) { Log.d(TAG, "DocumentSnapshot added with ID: " + documentReference.getId()); } }) .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { Log.w(TAG, "Error adding document", e); } });
Dart
// Create a new user with a first and last name final user = <String, dynamic>{ "first": "Ada", "last": "Lovelace", "born": 1815 }; // Add a new document with a generated ID db.collection("users").add(user).then((DocumentReference doc) => print('DocumentSnapshot added with ID: ${doc.id}'));
C++
// Add a new document with a generated ID Future<DocumentReference> user_ref = db->Collection("users").Add({{"first", FieldValue::String("Ada")}, {"last", FieldValue::String("Lovelace")}, {"born", FieldValue::Integer(1815)}}); user_ref.OnCompletion([](const Future<DocumentReference>& future) { if (future.error() == Error::kErrorOk) { std::cout << "DocumentSnapshot added with ID: " << future.result()->id() << std::endl; } else { std::cout << "Error adding document: " << future.error_message() << std::endl; } });
Unity
DocumentReference docRef = db.Collection("users").Document("alovelace"); Dictionary<string, object> user = new Dictionary<string, object> { { "First", "Ada" }, { "Last", "Lovelace" }, { "Born", 1815 }, }; docRef.SetAsync(user).ContinueWithOnMainThread(task => { Debug.Log("Added data to the alovelace document in the users collection."); });
עכשיו מוסיפים עוד מסמך לאוסף users. שימו לב שהמסמך הזה כולל צמד מפתח/ערך (שם אמצעי) שלא מופיע במסמך הראשון. מסמכים באוסף יכולים להכיל קבוצות שונות של מידע.
גרסה 9 לאינטרנט
// Add a second document with a generated ID. import { addDoc, collection } from "firebase/firestore"; try { const docRef = await addDoc(collection(db, "users"), { first: "Alan", middle: "Mathison", last: "Turing", born: 1912 }); console.log("Document written with ID: ", docRef.id); } catch (e) { console.error("Error adding document: ", e); }
גרסה 8 לאינטרנט
// Add a second document with a generated ID. db.collection("users").add({ first: "Alan", middle: "Mathison", last: "Turing", born: 1912 }) .then((docRef) => { console.log("Document written with ID: ", docRef.id); }) .catch((error) => { console.error("Error adding document: ", error); });
Swift
// Add a second document with a generated ID. do { let ref = try await db.collection("users").addDocument(data: [ "first": "Alan", "middle": "Mathison", "last": "Turing", "born": 1912 ]) print("Document added with ID: \(ref.documentID)") } catch { print("Error adding document: \(error)") }
Objective-C
// Add a second document with a generated ID. __block FIRDocumentReference *ref = [[self.db collectionWithPath:@"users"] addDocumentWithData:@{ @"first": @"Alan", @"middle": @"Mathison", @"last": @"Turing", @"born": @1912 } completion:^(NSError * _Nullable error) { if (error != nil) { NSLog(@"Error adding document: %@", error); } else { NSLog(@"Document added with ID: %@", ref.documentID); } }];
Kotlin
Android
// Create a new user with a first, middle, and last name val user = hashMapOf( "first" to "Alan", "middle" to "Mathison", "last" to "Turing", "born" to 1912, ) // Add a new document with a generated ID db.collection("users") .add(user) .addOnSuccessListener { documentReference -> Log.d(TAG, "DocumentSnapshot added with ID: ${documentReference.id}") } .addOnFailureListener { e -> Log.w(TAG, "Error adding document", e) }
Java
Android
// Create a new user with a first, middle, and last name Map<String, Object> user = new HashMap<>(); user.put("first", "Alan"); user.put("middle", "Mathison"); user.put("last", "Turing"); user.put("born", 1912); // Add a new document with a generated ID db.collection("users") .add(user) .addOnSuccessListener(new OnSuccessListener<DocumentReference>() { @Override public void onSuccess(DocumentReference documentReference) { Log.d(TAG, "DocumentSnapshot added with ID: " + documentReference.getId()); } }) .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { Log.w(TAG, "Error adding document", e); } });
Dart
// Create a new user with a first and last name final user = <String, dynamic>{ "first": "Alan", "middle": "Mathison", "last": "Turing", "born": 1912 }; // Add a new document with a generated ID db.collection("users").add(user).then((DocumentReference doc) => print('DocumentSnapshot added with ID: ${doc.id}'));
C++
db->Collection("users") .Add({{"first", FieldValue::String("Alan")}, {"middle", FieldValue::String("Mathison")}, {"last", FieldValue::String("Turing")}, {"born", FieldValue::Integer(1912)}}) .OnCompletion([](const Future<DocumentReference>& future) { if (future.error() == Error::kErrorOk) { std::cout << "DocumentSnapshot added with ID: " << future.result()->id() << std::endl; } else { std::cout << "Error adding document: " << future.error_message() << std::endl; } });
Unity
DocumentReference docRef = db.Collection("users").Document("aturing"); Dictionary<string, object> user = new Dictionary<string, object> { { "First", "Alan" }, { "Middle", "Mathison" }, { "Last", "Turing" }, { "Born", 1912 } }; docRef.SetAsync(user).ContinueWithOnMainThread(task => { Debug.Log("Added data to the aturing document in the users collection."); });
קריאת נתונים
אפשר להשתמש בכלי להצגת נתונים במסוף Firebase כדי לוודא במהירות שהוספתם נתונים ל-Firestore.
אפשר גם להשתמש בשיטה get כדי לאחזר את כל האוסף.
גרסה 9 לאינטרנט
import { collection, getDocs } from "firebase/firestore"; const querySnapshot = await getDocs(collection(db, "users")); querySnapshot.forEach((doc) => { console.log(`${doc.id} => ${doc.data()}`); });
גרסה 8 לאינטרנט
db.collection("users").get().then((querySnapshot) => { querySnapshot.forEach((doc) => { console.log(`${doc.id} => ${doc.data()}`); }); });
Swift
do { let snapshot = try await db.collection("users").getDocuments() for document in snapshot.documents { print("\(document.documentID) => \(document.data())") } } catch { print("Error getting documents: \(error)") }
Objective-C
[[self.db collectionWithPath:@"users"] getDocumentsWithCompletion:^(FIRQuerySnapshot * _Nullable snapshot, NSError * _Nullable error) { if (error != nil) { NSLog(@"Error getting documents: %@", error); } else { for (FIRDocumentSnapshot *document in snapshot.documents) { NSLog(@"%@ => %@", document.documentID, document.data); } } }];
Kotlin
Android
db.collection("users") .get() .addOnSuccessListener { result -> for (document in result) { Log.d(TAG, "${document.id} => ${document.data}") } } .addOnFailureListener { exception -> Log.w(TAG, "Error getting documents.", exception) }
Java
Android
db.collection("users") .get() .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() { @Override public void onComplete(@NonNull Task<QuerySnapshot> task) { if (task.isSuccessful()) { for (QueryDocumentSnapshot document : task.getResult()) { Log.d(TAG, document.getId() + " => " + document.getData()); } } else { Log.w(TAG, "Error getting documents.", task.getException()); } } });
Dart
await db.collection("users").get().then((event) { for (var doc in event.docs) { print("${doc.id} => ${doc.data()}"); } });
C++
Future<QuerySnapshot> users = db->Collection("users").Get(); users.OnCompletion([](const Future<QuerySnapshot>& future) { if (future.error() == Error::kErrorOk) { for (const DocumentSnapshot& document : future.result()->documents()) { std::cout << document << std::endl; } } else { std::cout << "Error getting documents: " << future.error_message() << std::endl; } });
Unity
CollectionReference usersRef = db.Collection("users"); usersRef.GetSnapshotAsync().ContinueWithOnMainThread(task => { QuerySnapshot snapshot = task.Result; foreach (DocumentSnapshot document in snapshot.Documents) { Debug.Log(String.Format("User: {0}", document.Id)); Dictionary<string, object> documentDictionary = document.ToDictionary(); Debug.Log(String.Format("First: {0}", documentDictionary["First"])); if (documentDictionary.ContainsKey("Middle")) { Debug.Log(String.Format("Middle: {0}", documentDictionary["Middle"])); } Debug.Log(String.Format("Last: {0}", documentDictionary["Last"])); Debug.Log(String.Format("Born: {0}", documentDictionary["Born"])); } Debug.Log("Read all data from the users collection."); });
אבטחת הנתונים
כדי לאבטח את הנתונים ב-Firestore במצב Native, אפשר להשתמש ב-אימות ב-Firebase ובכללי אבטחה של Firestore.
ריכזנו כאן כמה קבוצות כללים בסיסיות שתוכלו להשתמש בהן כדי להתחיל. אפשר לשנות את כללי האבטחה במסוף Firebase דרך Databases & Storage (מסדי נתונים ואחסון) > Firestore > הכרטיסייה Rules (כללים).
נדרש אימות
// Allow read/write access on all documents to any user signed in to the application
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.auth != null;
}
}
}
מצב נעילה
// Deny read/write access to all users under any conditions
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
}
}
מצב בדיקה
// Allow read/write access to all users under any conditions
// Warning: **NEVER** use this rule set in production; it allows
// anyone to overwrite your entire database.
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if true;
}
}
}
לפני שפורסים את אפליקציית האינטרנט, Android או iOS בסביבת הייצור, צריך גם לבצע פעולות כדי לוודא שרק לקוחות האפליקציה יכולים לגשת לנתונים שלכם ב-Firestore במצב Native. מידע נוסף זמין במאמרי העזרה בנושא App Check.
צפייה בסרטון הדרכה
כדי לקבל הנחיות מפורטות לתחילת העבודה עם ספריות הלקוח של Firestore לנייד ולאינטרנט, אפשר לצפות באחד ממדריכי הווידאו הבאים:
אינטרנט
iOS
Android
סרטונים נוספים זמינים בערוץ YouTube של Firebase.
השלבים הבאים
כדי להעמיק את הידע שלכם, כדאי לעיין בנושאים הבאים:
- Codelabs – כדי ללמוד איך להשתמש ב-Firestore במצב Native באפליקציה אמיתית, אפשר לעקוב אחר ה-codelab ל-Android, ל-iOS או ל-Web.
- מודל נתונים – מידע נוסף על מבנה הנתונים ב-Firestore, כולל נתונים היררכיים ותתי-אוספים.
- הוספת נתונים – מידע נוסף על יצירה ועדכון של נתונים ב-Firestore.
- קבלת נתונים – מידע נוסף על אחזור נתונים.
- איך מבצעים שאילתות פשוטות ומורכבות
- הזמנה והגבלה של שאילתות – כאן מוסבר איך להזמין ולהגביל את הנתונים שמוחזרים על ידי השאילתות.