在Xamarin.Forms中使用Firesharp实现Firebase数据库食谱数据的推送与获取
Got it, let's walk through how to implement Firebase data push and fetch for your Recipe model in Xamarin.Forms using FireSharp. I'll break this down step by step to make it easy to follow:
First off, you need to install the FireSharp package in your Xamarin.Forms project. Head to NuGet Package Manager, search for FireSharp, and install the latest stable version.
Next, grab your Firebase project credentials from the Firebase Console:
- Go to your project → Project Settings → Service Accounts → Generate New Private Key (you'll get a JSON file)
- Extract the
auth_secretanddatabaseURLfrom that file—you'll need these to initialize the FireSharp client.
It looks like your Recipe class was cut off (you had public string pi...). I'll assume that's a pictureUrl property for a recipe image. Also, adding [Serializable] ensures FireSharp can serialize/deserialize the class properly:
[Serializable] public class Recipe { public string title { get; set; } public string workTime { get; set; } public string degreeOfDifficulty { get; set; } public string caloriesPerPerson { get; set; } public string preparation { get; set; } public string cookingBakingTime { get; set; } public string restTime { get; set; } public int portions { get; set; } public string pictureUrl { get; set; } // Completed the truncated property }
If you want to map a property to a different key in Firebase (e.g., title → recipe_title), add the [JsonProperty] attribute from Newtonsoft.Json:
[JsonProperty("recipe_title")] public string title { get; set; }
Create a reusable client instance (I recommend putting this in App.xaml.cs so it's accessible across your app):
using FireSharp.Config; using FireSharp.Interfaces; using FireSharp; public partial class App : Application { // FireSharp config and client private static IFirebaseConfig _firebaseConfig = new FirebaseConfig { AuthSecret = "YOUR_FIREBASE_AUTH_SECRET", // Replace with your auth secret BasePath = "https://YOUR_PROJECT_ID.firebaseio.com/" // Replace with your database URL }; public static IFirebaseClient FirebaseClient { get; private set; } public App() { InitializeComponent(); FirebaseClient = new FirebaseClient(_firebaseConfig); MainPage = new MainPage(); } }
Write an async method to send your Recipe object to Firebase. FireSharp will automatically generate a unique key for each recipe, or you can specify your own if needed:
public async Task PushNewRecipeAsync(Recipe newRecipe) { try { // Push the recipe to the "recipes" node in Firebase var response = await App.FirebaseClient.PushAsync("recipes/", newRecipe); // Get the auto-generated key for the new recipe (useful for later fetching) string recipeKey = response.Result.Name; Console.WriteLine($"Recipe added successfully! Key: {recipeKey}"); } catch (Exception ex) { // Handle errors (e.g., network issues, invalid credentials) Console.WriteLine($"Error pushing recipe: {ex.Message}"); // Show a user-friendly alert in Xamarin.Forms await App.Current.MainPage.DisplayAlert("Error", "Failed to save recipe. Please try again.", "OK"); } }
Call this method when you want to save a recipe (e.g., from a form submission):
// Example: Create a sample recipe var chocolateCake = new Recipe { title = "Classic Chocolate Cake", workTime = "30 minutes", degreeOfDifficulty = "Medium", caloriesPerPerson = "450", preparation = "Mix flour, cocoa powder, sugar, then add eggs, milk, and oil...", cookingBakingTime = "25 minutes", restTime = "1 hour", portions = 8, pictureUrl = "https://example.com/chocolate-cake.jpg" }; // Push to Firebase await PushNewRecipeAsync(chocolateCake);
Let's cover two common scenarios: fetching a single recipe by its key, and fetching all recipes.
5.1 Fetch a Single Recipe by Key
Use this method to retrieve a specific recipe using its auto-generated key:
public async Task<Recipe> GetRecipeByKeyAsync(string recipeKey) { try { var response = await App.FirebaseClient.GetAsync($"recipes/{recipeKey}"); // Deserialize the response into a Recipe object Recipe recipe = response.ResultAs<Recipe>(); return recipe; } catch (Exception ex) { Console.WriteLine($"Error fetching recipe: {ex.Message}"); await App.Current.MainPage.DisplayAlert("Error", "Failed to load recipe.", "OK"); return null; } }
Call it like this:
var recipe = await GetRecipeByKeyAsync("YOUR_RECIPE_KEY_HERE"); if (recipe != null) { // Update your UI with the recipe data TitleLabel.Text = recipe.title; PrepTimeLabel.Text = $"Prep Time: {recipe.workTime}"; // ... populate other UI elements }
5.2 Fetch All Recipes
To get all recipes stored in the "recipes" node:
public async Task<List<Recipe>> GetAllRecipesAsync() { try { var response = await App.FirebaseClient.GetAsync("recipes/"); // Firebase returns a dictionary where keys are recipe IDs and values are Recipe objects var recipesDictionary = response.ResultAs<Dictionary<string, Recipe>>(); if (recipesDictionary == null) return new List<Recipe>(); // Convert the dictionary to a list (optional: keep the recipe key if you need it) var recipesList = recipesDictionary.Select(kv => { // If you want to store the key in the Recipe model, add a "Id" property: // kv.Value.Id = kv.Key; return kv.Value; }).ToList(); return recipesList; } catch (Exception ex) { Console.WriteLine($"Error fetching all recipes: {ex.Message}"); await App.Current.MainPage.DisplayAlert("Error", "Failed to load recipes.", "OK"); return new List<Recipe>(); } }
Bind the list to a ListView in your Xamarin.Forms UI:
var allRecipes = await GetAllRecipesAsync(); RecipeListView.ItemsSource = allRecipes;
- Firebase Rules: For testing, you can set your database rules to allow public read/write, but lock this down for production! Go to Firebase Console → Database → Rules and update to something like:
{ "rules": { "recipes": { ".read": "auth != null", ".write": "auth != null" } } } - Threading: When updating UI after async operations, use
Device.BeginInvokeOnMainThreadif needed (though most Xamarin.Forms controls handle async updates automatically now). - Serialization: Ensure all properties in your Recipe class are public—FireSharp needs this to serialize/deserialize correctly.
内容的提问来源于stack exchange,提问作者Dahl93

